"""New version of the product started February, 8th. Without scientific classification, use content-type for further classification."""
"""Echo collection provides the classes for the ECHO content web-site.
class ECHO_collection is the basis class for an ECHO collection.
class ECHO_resource contains information on ECHO resources (e.g. an Display environment for Metadata
class ECHO_externalLink contains information on externalLinks
"""
import string
import re
import os
import OFS.Image
from types import *
from OFS.Cache import Cacheable
from OFS.Image import Image
from Globals import DTMLFile
from OFS.Folder import Folder
from OFS.SimpleItem import SimpleItem
from AccessControl import ClassSecurityInfo
from AccessControl.User import UserFolder
from Globals import InitializeClass
from Globals import DTMLFile
import Globals
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.PageTemplates.PageTemplate import PageTemplate
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
from Globals import Persistent, package_home
from Acquisition import Implicit
from ECHO_helpers import displayTypes, getText,readFieldFromXML
import urllib
import smtplib
import time
from Ft.Xml.Domlette import NonvalidatingReader
from Ft.Xml.Domlette import PrettyPrint
from Ft.Xml import EMPTY_NAMESPACE
import Ft.Xml.XPath
import cStringIO
import zLOG
try:
from psycopg import libpq
except:
try:
from pyPgSQL import libpq
except:
print "ECHO_collection: Warning - No libpq imported!"
import xml.dom.minidom
import urllib
import xml.dom.minidom
from ECHO_graphicalOverview import javaHandler,javaScriptMain
import ECHO_helpers
def donatus(txt2):
import xmlrpclib
server = xmlrpclib.ServerProxy("http://archimedes.fas.harvard.edu/cgi-bin/donatus-rpc")
txt=txt2.encode('utf-8')
bin=xmlrpclib.Binary(txt)
ret=server.donatus.analyze(bin)
return ret['morphData'].data
def donatusVariant2Lemma(morphData):
"""creates hash variant -> morphdata"""
ret={}
dom=xml.dom.minidom.parseString(morphData)
lemmas=dom.getElementsByTagName('lemma')
for lemma in lemmas:
variants=lemma.getElementsByTagName('variant')
for variant in variants:
atr=variant.getAttribute('form')
if ret.has_key(atr):
ret[atr].append=lemma.getAttribute('form')
else:
ret[atr]=[lemma.getAttribute('form')]
return ret
#regexp for extracting elements from xml
patternTXT=r"<\s*txt.*?>(.*?)</txt>"
regexpTXT = re.compile(patternTXT, re.IGNORECASE + re.DOTALL)
patternPage=r"<\s*page.*?>(.*?)</page>"
regexpPage = re.compile(patternPage, re.IGNORECASE + re.DOTALL)
def ECHO_rerenderLinksMD(self,obj=None,types=['title','label']):
"""Rerender all Links"""
ret=""
if not obj:
obj = self
entries=obj.ZopeFind(obj,obj_metatypes=['ECHO_resource'],search_sub=1)
for entry in entries:
if entry[1].meta_type == 'ECHO_resource':
try:
entry[1].ECHO_getResourceMD(template="no")
if "title" in types:
entry[1].generate_title()
if "label" in types:
entry[1].generate_label()
ret+="OK:"+entry[0]+"-- "+entry[1].getTitle().decode('utf-8')+"-- "+entry[1].getTitle().decode('utf-8')+"<br>"
except:
ret+="Error:"+entry[0]+"<br>"
return "<html><body>"+ret+"Rerenderd all links to resources in: "+self.title+"</html></body>"
def reloadMetaDataFromStorage(self,RESPONSE=None):
"""copy metadata from the storage to ECHO"""
ret=""
resources=self.ZopeFind(self,obj_metatypes=['ECHO_resource'],search_sub=1)
for resource in resources:
x=str(resource[1].copyIndex_meta2echo_resource())+"<br>"
ret+=x
#print x
if RESPONSE is not None:
#RESPONSE.redirect('./manage_main')
return "<html><body>"+ret+"</html></body>"
return ret
def getRDFDescription(self,linkURL,urn=None,nameDef=None,typeName=None):
"""rdf"""
ret=""
about="""<RDF:Description RDF:about="%s">"""
name="""<ECHONAVIGATION:name>%s</ECHONAVIGATION:name>"""
link="""<ECHONAVIGATION:link xlink:href="%s">%s</ECHONAVIGATION:link>"""
clickable="""<ECHONAVIGATION:linkClickable>%s</ECHONAVIGATION:linkClickable>"""
#link="""<ECHONAVIGATION:link RDF:about="%s"/>"""
type="""<ECHONAVIGATION:type>%s</ECHONAVIGATION:type>"""
#xlink="""<ECHONAVIGATION:xlink xlink:href="%s"/>"""
if not urn:
#urn="urn:"+re.sub('/',':',self.absolute_url())
urn=self.absolute_url()
about2=about%urn
if not nameDef:
if hasattr(self,'label') and not (self.label==""):
name2=name%self.label
elif not self.title=="":
name2=name%self.title
else:
name2=name%self.getId()
name2=re.sub('&','&',name2)
else:
name2=name%nameDef
linkURL=re.sub('http:','',linkURL)
linkURL2=re.sub('&','&',linkURL)
link2=link%(("http:"+linkURL2),("http:"+urllib.quote(linkURL)))
clickable2=clickable%"true"
if not typeName:
type2=type%self.meta_type
else:
type2=type%typeName
#ret=about2+"\n"+name2+"\n"+link2+"\n"+type2+"\n"+clickable2+"\n</RDF:Description>"
ret=about2+"\n"+name2+"\n"+type2+"\n"+clickable2+"\n</RDF:Description>"
return ret
def getCopyrightsFromForm(self,argv):
medias={}
partners={}
copyrights={}
copyrightsFinal=[]
for arg in argv.keys():
if arg[0:5]=='media':
nm=int(arg[5:])
medias[nm]=argv[arg]
elif arg[0:5]=='partn':
nm=int(arg[5:])
partners[nm]=argv[arg]
elif arg[0:5]=='copyr':
nm=int(arg[5:])
copyrights[nm]=argv[arg]
copyrightsList=[(medias[nm],partners[nm],copyrights[nm]) for nm in medias.keys()]
for copyright in copyrightsList:
if copyright[2]=='institution0000':
copyrightsFinal.append((copyright[0],copyright[1],self.getPartnerCopyright(copyright[1],'')))
else:
if not copyright[0]=='':
copyrightsFinal.append(copyright)
return copyrightsFinal
#List of different types for the graphical linking viewer
viewClassificationListMaster=['view point','area']
def checkDiffs(self,metadict):
"""check differences"""
def NoneToEmpty(obj):
if obj:
return obj
else:
return ""
diffs={}
tags=self.findTagsFromMapping(self.contentType)
self.referencetypes=tags[2]
self.fields=tags[3]
for field in tags[1]:
try:
if (NoneToEmpty(self.getFieldValue(self.getFieldTag(tags,field)))==metadict[self.getFieldTag(tags,field)]):
diffs[self.getFieldTag(tags,field)]=1
else:
diffs[self.getFieldTag(tags,field)]=0
except:
diffs[self.getFieldTag(tags,field)]=0
return diffs
def content_html(self,type):
"""template fuer content"""
#templates = self.ZopeFind(self.aq_parent,obj_ids=[type+"_template"])
#
#if templates:
# return templates[0][1]()
if hasattr(self,type+"_template"):
obj=getattr(self,type+"_template")
return obj()
else:
pt=PageTemplateFile('Products/ECHO_content/zpt/ECHO_%s_template_standard.zpt'%type).__of__(self)
pt.content_type="text/html"
return pt()
def toList(field):
"""Einzelfeld in Liste umwandeln"""
if type(field)==StringType:
return [field]
else:
return field
def getTextFromNode(nodename):
nodelist=nodename.childNodes
rc = ""
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc = rc + node.data
return rc
def sendFile(self, filename, type):
"""sends an object or a local file (in the product) as response"""
paths = filename.split('/')
object = self
# look for an object called filename
for path in paths:
if hasattr(object, path):
object = getattr(object, path)
else:
object = None
break
if object:
# if the object exists then send it
return object.index_html(self.REQUEST.REQUEST, self.REQUEST.RESPONSE)
else:
# send a local file with the given content-type
fn = os.path.join(package_home(globals()), filename)
self.REQUEST.RESPONSE.setHeader("Content-Type", type)
self.REQUEST.RESPONSE.write(file(fn).read())
return
class BrowserCheck:
"""check the browsers request to find out the browser type"""
def __init__(self, zope):
self.ua = zope.REQUEST.get_header("HTTP_USER_AGENT")
self.isN4 = (string.find(self.ua, 'Mozilla/4.') > -1) and (string.find(self.ua, 'MSIE') < 0)
self.isIE = string.find(self.ua, 'MSIE') > -1
self.nav = self.ua[string.find(self.ua, '('):]
ie = string.split(self.nav, "; ")[1]
if string.find(ie, "MSIE") > -1:
self.versIE = string.split(ie, " ")[1]
self.isMac = string.find(self.ua, 'Macintosh') > -1
self.isWin = string.find(self.ua, 'Windows') > -1
self.isIEWin = self.isIE and self.isWin
self.isIEMac = self.isIE and self.isMac
def writeMetadata(url,metadict,project=None,startpage=None,xslt=None,thumbtemplate=None,topbar=None,digiLibTemplate=None,xmlfrag=None,digiliburlprefix=None):
"""Einlesen der Metadaten und und erstellen des geaenderten XML file"""
def updateTextToolNode(tag,value):
#print dom,tag,value
metanode=dom.getElementsByTagName('texttool')[0]
try:
nodeOld=metanode.getElementsByTagName(tag)
except:
nodeOld=None
if nodeOld:
metanode.removeChild(nodeOld[0]).unlink()
node=dom.createElement(tag)
nodetext=dom.createTextNode(value)
node.appendChild(nodetext)
metanode.appendChild(node)
if xmlfrag:
geturl="""<?xml version="1.0" ?>
<resource type="MPIWG">
<meta>
<bib type="Book">
</bib>
</meta>
</resource>"""
dom=xml.dom.minidom.parseString(geturl)
else:
try:
geturl=""
for line in ECHO_helpers.urlopen(url).readlines():
geturl=geturl+line
except:
return (None,"Cannot open: "+url)
try:
dom=xml.dom.minidom.parseString(geturl)
except:
return (None,"Cannot parse: "+url+"<br>"+geturl)
metanodes=dom.getElementsByTagName('bib')
if not metanodes:
metanodes=dom.getElementsByTagName('archimedes')
metanode=metanodes[0]
for metaData in metadict.keys():
try:
nodeOld=metanode.getElementsByTagName(metaData)
except:
nodeOld=None
if nodeOld:
metanode.removeChild(nodeOld[0]).unlink()
else:
# try also old writing rule - instead of _:
try:
nodeOld=metanode.getElementsByTagName(re.sub('_','-',metaData))
except:
nodeOld=None
if nodeOld:
metanode.removeChild(nodeOld[0]).unlink()
metanodeneu=dom.createElement(metaData)
metanodetext=dom.createTextNode(metadict[metaData])
#try:
#metanodetext=dom.createTextNode(unicode(metadict[metaData],"utf-8"))
#except:
#metanodetext=dom.createTextNode(metadict[metaData].encode('utf-8'))
metanodeneu.appendChild(metanodetext)
metanode.appendChild(metanodeneu)
if project:
updateTextToolNode('project',project)
if startpage:
updateTextToolNode('startpage',startpage)
if topbar:
updateTextToolNode('toptemplate',topbar)
if thumbtemplate:
updateTextToolNode('thumbtemplate',thumbtemplate)
if xslt:
updateTextToolNode('xslt',xslt)
if digiliburlprefix:
updateTextToolNode('digiliburlprefix',digiliburlprefix)
try:
return dom.toxml().encode('utf-8')
except:
return dom.toxml('utf-8')
def readMetadata(url):
"""Methode zum Auslesen der Metadateninformation zu einer Resource
Vorerst noch Typ bib"""
metadict={}
try:
geturl=""
for line in ECHO_helpers.urlopen(url).readlines():
geturl=geturl+line
except:
return (None,"Cannot open: "+url)
try:
dom=xml.dom.minidom.parseString(geturl)
except:
return (None,"Cannot parse: "+url+"<br>"+geturl)
metanode=dom.getElementsByTagName('bib')
metadict['bib_type']='Book'
if len(metanode)==0:
metanode=dom.getElementsByTagName('archimedes')
metadict['bib_type']='Archimedes'
if not len(metanode)==0:
metacontent=metanode[0].childNodes
try:
metadict['bib_type']=getText(dom.getElementsByTagName('bib')[0].attributes['type'].childNodes)
except:
"""nothing"""
for node in metacontent:
try:
#print urllib.unquote(getText(node.childNodes)),getText(node.childNodes)
metadict[re.sub('-','_',node.tagName.lower())]=urllib.unquote(getText(node.childNodes))
except:
"""nothing"""
return metadict,""
def setECHO_collectionInformation(self,title,label,description,contentType,responsible,credits,weight,coordstrs,viewClassification=""):
"""Allegemeine Informationen zu einer ECHO Collection"""
self.viewClassification=viewClassification
self.label = label
self.title=title
self.description=description
self.contentType=contentType
self.responsible=responsible
self.credits=toList(credits)
self.weight=weight
coords=[]
#coordinates of for rectangles
if coordstrs:
for coordstr in coordstrs:
try:
temco=coordstr.split(",")
except:
temco=[]
coords.append(temco)
self.coords=coords[0:]
class ECHO_copyright(Folder):
"""Copyright informationen"""
meta_type="ECHO_copyright"
def __init__(self,id,title,copyrights):
"""init"""
self.title=title
self.id=id
self.copyrights=copyrights[0:]
def getCopyrights(self):
"""return coyprights"""
return self.copyrights
manage_options = Folder.manage_options+(
{'label':'Main Config','action':'ECHO_copyright_configForm'},
)
def ECHO_copyright_configForm(self):
"""change form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_copyright').__of__(self)
pt.content_type="text/html"
return pt()
def ECHO_copyright_config(self,title,RESPONSE=None):
"""change"""
self.title=title
self.copyrights=[]
self.copyrights=getCopyrightsFromForm(self,self.REQUEST.form)[0:]
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def manage_addECHO_copyrightForm(self):
"""Form for adding"""
pt=PageTemplateFile('Products/ECHO_content/zpt/AddECHO_copyright.zpt').__of__(self)
return pt()
def manage_addECHO_copyright(self, id,title,RESPONSE=None):
"""add the copyright"""
meta_type="ECHO_copyright"
#first generate copyrights as list of tripels (mediaType,partner,copyrightType)
self._setObject(id, ECHO_copyright(id, title,getCopyrightsFromForm(self,self.REQUEST.form)))
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
class ECHO_layoutTemplate(ZopePageTemplate):
"""Create a layout Template for different purposes"""
meta_type="ECHO_layoutTemplate"
def __init__(self, id, text=None, content_type=None,EchoType=None):
self.id = str(id)
self.ZBindings_edit(self._default_bindings)
if text is None:
self._default_content_fn = os.path.join(package_home(globals()),
'zpt/ECHO_%s_template_standard.zpt'%EchoType)
text = open(self._default_content_fn).read()
self.pt_edit(text, content_type)
"""change form"""
def manage_addECHO_layoutTemplateForm(self):
"""Form for adding"""
pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/AddECHO_layoutTemplate.zpt')).__of__(self)
return pt()
from urllib import quote
def manage_addECHO_layoutTemplate(self, EchoType,title=None,REQUEST=None):
"Add a Page Template with optional file content."
if type(EchoType)==StringType:
EchoTypes=[EchoType]
else:
EchoTypes=EchoType
for singleType in EchoTypes:
id = str(singleType)+"_template"
if REQUEST is None:
self._setObject(id, ECHO_layoutTemplate(id, text,EchoType=singleType))
ob = getattr(self, id)
if title:
ob.pt_setTitle(title)
return ob
else:
file = REQUEST.form.get('file')
headers = getattr(file, 'headers', None)
if headers is None or not file.filename:
zpt = ECHO_layoutTemplate(id,EchoType=singleType)
else:
zpt = ECHO_layoutTemplate(id, file, headers.get('content_type'))
self._setObject(id, zpt)
ob = getattr(self, id)
if title:
ob.pt_setTitle(title)
try:
u = self.DestinationURL()
except AttributeError:
u = REQUEST['URL1']
REQUEST.RESPONSE.redirect(u+'/manage_main')
return ''
class ECHO_fullText(ZopePageTemplate):
"""echo fulltext in xml"""
meta_type="ECHO_fullText"
def donatusVariant2Lemma(self,nr='1'):
"""analyze by donatus"""
return donatusVariant2Lemma(donatus(self.lemmatize(nr)))
def tagLex(self,nr="1"):
"""generate Links"""
global retLex
global toggle
toggle=0
retLex=""
lemmatized=self.lemmatize(nr)[0:]
#print "ho",repr(lemmatized)
variants=donatusVariant2Lemma(donatus(lemmatized))
def createTag(name,attrs):
global toggle
if name=="w":
toggle=1
return ""
else:
tag="<"
tag+=name
for attr in attrs.keys():
tag+=""" %s="%s" """%(attr,attrs[attr])
tag+=">"
return tag
def createData(data):
global toggle
astring="""<a href="http://141.14.236.86/cgi-bin/toc/dict?step=remotetable;word=%s;lang=de" target="_blank">%s</a> """
if toggle: # tag war ein w
toggle=0
if variants.has_key(data):
return astring%(variants[data][0],data)
else:
return astring%(data,data)
# 3 handler functions
def start_element(name, attrs):
global retLex
retLex+=createTag(name,attrs)
def end_element(name):
global retLex
if not name=="w":
retLex+="</%s>"%(name.encode('utf-8'))
def char_data(data):
global retLex
if data:
try:
retLex+=createData(data)
except:
"""no"""
p = xml.parsers.expat.ParserCreate()
p.StartElementHandler = start_element
p.EndElementHandler = end_element
p.CharacterDataHandler = char_data
p.Parse(lemmatized.encode('utf-8'),1)
#print repr(lemmatized.encode('utf-8'))
return retLex
def lemmatize(self,nr='1',lang="de"):
"""lemmatize"""
global ret
ret=""
def createTag(name,attrs):
tag="<"
tag+=name
for attr in attrs.keys():
tag+=""" %s="%s" """%(attr,attrs[attr])
tag+=">"
return tag
def insertW(str):
splitted=str.split()
wordlist=["<w>%s</w>"%split for split in splitted]
return string.join(wordlist,'\n')
# 3 handler functions
def start_element(name, attrs):
global ret
ret+=createTag(name,attrs)
def end_element(name):
global ret
ret+="</%s>"%(name.encode('utf-8'))
def char_data(data):
global ret
ret+=insertW(data)
p = xml.parsers.expat.ParserCreate()
p.StartElementHandler = start_element
p.EndElementHandler = end_element
p.CharacterDataHandler = char_data
p.Parse(self.getPage(nr), 1)
txt="""<wtag locator="xxx">
<section lang="%s"><s>%s</s></section>
</wtag>"""
ret=txt%(lang,ret)
return ret
def getPage(self,nr='1'):
"""get page n"""
dom=xml.dom.minidom.parseString(self())
pages=dom.getElementsByTagName('page')
return pages[int(nr)-1].toxml('utf-8')
# Product registration and Add support
manage_addECHO_fullTextForm = PageTemplateFile(
'zpt/AddECHO_fullText.zpt', globals())
from urllib import quote
def manage_addECHO_fullText(self, id, title=None, text=None,
REQUEST=None, submit=None):
"Add a Page Template with optional file content."
id = str(id)
if REQUEST is None:
self._setObject(id, ECHO_fullText(id, text))
ob = getattr(self, id)
if title:
ob.pt_setTitle(title)
return ob
else:
file = REQUEST.form.get('file')
headers = getattr(file, 'headers', None)
if headers is None or not file.filename:
zpt = ECHO_fullText(id)
else:
zpt = ECHO_fullText(id, file, headers.get('content_type'))
self._setObject(id, zpt)
try:
u = self.DestinationURL()
except AttributeError:
u = REQUEST['URL1']
if submit == " Add and Edit ":
u = "%s/%s" % (u, quote(id))
REQUEST.RESPONSE.redirect(u+'/manage_main')
return ''
class ECHO_resource(Folder,Persistent):
"""ECHO Ressource"""
security=ClassSecurityInfo()
meta_type='ECHO_resource'
viewClassificationList=viewClassificationListMaster
getSubCols = ECHO_helpers.getSubCols
security.declareProtected('View','index_html')
def showRDF(self):
"""showrdf"""
self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
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"""
ret+=self.getRDF(urn="echo:colllectionroot")+"\n"
ret+="""</RDF:RDF>"""
return ret
def getRDF(self,urn=None):
"""rdf"""
ret=getRDFDescription(self,self.link,urn=urn)
return ret+self.createSubElementRDF(urn=urn)
def createSubElementRDF(self,urn=None):
"""rdf list"""
if not urn:
urn=self.absolute_url()
ret=""
rettemp="""<RDF:Seq RDF:about="%s">\n"""%urn
flag=0
li="""<RDF:li RDF:resource="%s" />\n"""
if not ('<error>' in self.getFullTextXML(noredirect='Yes')):
nurn=self.absolute_url()+'/getFullTextXML'
rettemp+=li%nurn
flag=1
if not ('<error>' in self.getImageView(noredirect='Yes')):
nurn=self.absolute_url()+'/getImageView'
rettemp+=li%nurn
flag=1
if not ('<error>' in self.showMetaDataXML()):
nurn=self.absolute_url()+'/showMetaDataXML'
rettemp+=li%nurn
flag=1
rettemp+="</RDF:Seq>"
if flag==1:
ret+=rettemp
if not ('<error>' in self.getFullTextXML(noredirect='Yes')):
nurn=self.absolute_url()+'/getFullTextXML'
ret+=getRDFDescription(self,self.absolute_url()+'/getFullTextXML',urn=nurn,nameDef="Fulltext",typeName="ECHO_fulltext")
if not ('<error>' in self.getImageView(noredirect='Yes')):
nurn=self.absolute_url()+'/getImageView'
ret+=getRDFDescription(self,self.absolute_url()+'/getImageView',urn=nurn,nameDef="Image View",typeName="ECHO_imageview")
if not ('<error>' in self.showMetaDataXML()):
nurn=self.absolute_url()+'/showMetaDataXML'
ret+=getRDFDescription(self,self.absolute_url()+'/showMetaDataXML',urn=nurn,nameDef="Metadata",typeName="ECHO_metaData")
return ret
def getAccessRightSelectorHTML(self,outlook="select"):
"""htmlselector"""
values=['free','mpiwg']
if outlook=="select":
ret="""<select name="%s">"""%self.getId()
for value in values:
if value==self.getAccessRightMD():
ret+="<option selected>%s</option>"%value
else:
ret+="<option>%s</option>"%value
return ret+"</select>"
else:
ret=""
for value in values:
if value==self.getAccessRightMD():
ret+="""<input type="radio" name="%s" value="%s" checked>%s"""%(self.getId(),value,value)
else:
ret+="""<input type="radio" name="%s" value="%s">%s"""%(self.getId(),value,value)
return ret
def getAccessRightMD(self):
"""set accessright"""
url=self.metalink
try:
geturl=""
for line in ECHO_helpers.urlopen(url).readlines():
geturl=geturl+line
except:
return (None,"Cannot open: "+url)
try:
dom=xml.dom.minidom.parseString(geturl)
root=dom.getElementsByTagName('resource')[0]
except:
return (None,"Cannot parse: "+url+"<br>"+geturl)
internal=dom.getElementsByTagName('internal')
if internal:
institution=dom.getElementsByTagName('institution')
return getText(institution[0].childNodes)
free=dom.getElementsByTagName('free')
if free:
return "free"
return "free" #default free
def changeAccessRightMD(self,accessright,RESPONSE=None):
"""change the rights"""
params="accessright=%s"%accessright
#print ECHO_helpers.urlopen(self.absolute_url()+'/setAccessRightXML'+'?'+params).read()
ECHO_helpers.urlopen('http://xserve02.mpiwg-berlin.mpg.de:18880/echo_nav/storage/downloadExternalXML?index_meta_url=%s&xml_url=%s'%(self.metalink,self.absolute_url()+'/setAccessRightXML'+urllib.quote('?'+params))).read()
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def setAccessRightXML(self,accessright):
"""set accessright"""
url=self.metalink
try:
geturl=""
for line in ECHO_helpers.urlopen(url).readlines():
geturl=geturl+line
except:
return (None,"Cannot open: "+url)
try:
dom=xml.dom.minidom.parseString(geturl)
root=dom.getElementsByTagName('resource')[0]
except:
return (None,"Cannot parse: "+url+"<br>"+geturl)
metanodes=dom.getElementsByTagName('access-conditions')
if not metanodes:
nodenew=dom.createElement('access-conditions')
root.appendChild(nodenew)
metanode=nodenew
else:
metanode=metanodes[0]
accesses=metanode.getElementsByTagName('access')
if not accesses:
nodenew2=dom.createElement('access')
metanode.appendChild(nodenew2)
metanode2=nodenew2
else:
metanode2=accesses[0]
internal=metanode.getElementsByTagName('internal')
if internal:
metanode2.removeChild(internal[0]).unlink()
free=metanode.getElementsByTagName('free')
if free:
metanode2.removeChild(internal[0]).unlink()
if accessright=='free':
nodenew3=dom.createElement('free')
metanode2.appendChild(nodenew3)
elif accessright=='mpiwg':
nodenew3=dom.createElement('internal')
nodenew4=dom.createElement('institution')
metanodetext=dom.createTextNode('mpiwg')
nodenew4.appendChild(metanodetext)
nodenew3.appendChild(nodenew4)
metanode2.appendChild(nodenew3)
return dom.toxml().encode('utf-8')
def setStartPageForm(self):
"""Form for changing the startpage"""
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_resourceStartPage.zpt').__of__(self)
pt.content_type="text/html"
return pt()
def createImageUrl(self,pn=1):
"""create ImageUrl"""
resourcepath=readFieldFromXML(self.metalink,'resource','archive-path').replace('/mpiwg/online','')
digiliburlprefix=readFieldFromXML(self.metalink,'texttool','digiliburlprefix')
images=readFieldFromXML(self.metalink,'texttool','image')
if (not resourcepath) or (not digiliburlprefix) or (not images):
zLOG.LOG("ECHO (createImageUrl)",zLOG.ERROR,"Cannot create ImageUrl for %s"%self.absolute_url())
return None
if not digiliburlprefix: digiliburlprefix="http://echo.mpiwg-berlin.mpg.de/zogilib?"
if (not images) or (not resourcepath): return None
return "%sfn=%s&pn=%i"%(digiliburlprefix,resourcepath+"/"+images,pn)
def copyTitleToInfoXML(self,RESPONSE=None):
"""copy title from the resource"""
presentationXML=readFieldFromXML(self.metalink,'texttool','presentation')
resourcepath=readFieldFromXML(self.metalink,'resource','archive-path')
if (not presentationXML) or (not resourcepath):
if RESPONSE:
RESPONSE.write("Error: %s\n"%self.getId())
else:
return None,self.absolute_url()
try:
fh=file(os.path.join(resourcepath,presentationXML),'w')
fh.write("""<info>
<author></author>
<title>%s</title>
<date></date>
<display>yes</display>
</info>"""%self.title)
fh.close()
return 1,self.getId()
except:
if RESPONSE:
RESPONSE.write("Error: %s\n"%self.getId())
else:
return None,self.absolute_url()
def setStartPage(self,startpage=None,RESPONSE=None):
"""set start page, if no startpage defined use the generic one of the resource"""
if (not (type(startpage)==StringType)):
if ("__generic" in startpage): # checke ob generic in der liste
startpage=self.absolute_url()+"/startpage_html"
elif ("__firstPage" in startpage): # checke ob generic in der liste
startpage=self.createImageUrl()
if (not startpage):
startpage=self.absolute_url()+"/startpage_html"
elif (startpage=="__generic"):
startpage=self.absolute_url()+"/startpage_html"
elif (startpage=="__firstPage"):
startpage=self.createImageUrl()
params="startpage=%s"%startpage
print 'http://xserve02.mpiwg-berlin.mpg.de:18880/echo_nav/storage/downloadExternalXML?index_meta_url=%s&xml_url=%s'%(self.metalink,self.absolute_url()+'/newMetaXML'+urllib.quote('?'+params))
ECHO_helpers.urlopen('http://xserve02.mpiwg-berlin.mpg.de:18880/echo_nav/storage/downloadExternalXML?index_meta_url=%s&xml_url=%s'%(self.metalink,self.absolute_url()+'/newMetaXML'+urllib.quote('?'+params))).read()
path=self.metalink
path=re.sub(self.REQUEST['SERVER_URL'],'',path)
path=re.sub('http://'+self.REQUEST['HTTP_HOST'],'',path)
path=re.sub('http://foxridge.mpiwg-berlin.mpg.de:8080','',path) # falls foxridge als server
path=re.sub('http://foxridge.mpiwg-berlin.mpg.de','',path) # falls foxridge als server
path=re.sub('http://foxridge.rz-berlin.mpg.de:8080','',path) # falls foxridge als server
path=re.sub('http://content.mpiwg-berlin.mpg.de','',path) # falls content als server
path=re.sub('http://foxridge.rz-berlin.mpg.de','',path) # falls foxridge als server
path=re.sub('http://vision.mpiwg-berlin.mpg.de','',path) # falls vision als server
path=re.sub('http://xserve02.mpiwg-berlin.mpg.de:18880','',path) # falls vision als server
path=re.sub('http://echo.mpiwg-berlin.mpg.de','',path) # falls echo
path=re.sub('/index.meta','',path)
ECHO_helpers.urlopen("http://nausikaa2.rz-berlin.mpg.de:86/cgi-bin/toc/admin/reg.cgi?path=%s"%path).readlines()
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def changeViewerTemplateSetForm(self):
"""change the viewer template set"""
pt=PageTemplateFile('Products/ECHO_content/zpt/changeResourceViewerTemplateSet').__of__(self)
return pt()
def getTextToolsField(self,name,default=''):
"""Lese Textoolsfelder aus index.meta im path aus"""
try:
dom=xml.dom.minidom.parse(self.metalink)
node=dom.getElementsByTagName('texttool')[0] #getNode
subnode=node.getElementsByTagName(name)[0]
# bei text wird nur der Folder gebraucht
if name=="text":
splitted=getText(subnode.childNodes).split("/")
return splitted[len(splitted)-2]
else:
return getText(subnode.childNodes)
except:
return default
def changeViewerTemplateSet(self,project,xslt,thumbtemplate,topbar,digiLibTemplate,digiliburlprefix,RESPONSE=None):
"""changeit"""
paramList=['project','startpage','xslt','thumbtemplate','topbar','digiLibTemplate','digiliburlprefix']
#writeMetadata(self.metalink,self.metaDataHash,project,None,xslt,thumbtemplate,topbar,digiLibTemplate)
params="project=%s&xslt=%s&thumbtemplate=%s&topbar=%s&digiLibTemplate=%s&digiliburlprefix=%s"%(project,xslt,thumbtemplate,topbar,digiLibTemplate,digiliburlprefix)
ECHO_helpers.urlopen('http://echo.mpiwg-berlin.mpg.de/echo_nav/storage/downloadExternalXML?index_meta_url=%s&xml_url=%s'%(self.metalink,self.absolute_url()+'/newMetaXML'+urllib.quote('?'+params))).read()
#print self.absolute_url()+'/newMetaXML'+urllib.quote'?'+params)
# hack Pfad auf die Dokumente
path=self.metalink
path=re.sub('/index.meta','',path)
path=re.sub(self.REQUEST['SERVER_URL'],'',path)
path=re.sub('http://'+self.REQUEST['HTTP_HOST'],'',path)
path=re.sub('http://foxridge.mpiwg-berlin.mpg.de:8080','',path) # falls foxridge als server
path=re.sub('http://foxridge.mpiwg-berlin.mpg.de:8080','',path) # falls foxridge als server
path=re.sub('http://foxridge.mpiwg-berlin.mpg.de','',path) # falls foxridge als server
path=re.sub('http://foxridge.rz-berlin.mpg.de:8080','',path) # falls foxridge als server
path=re.sub('http://foxridge.rz-berlin.mpg.de','',path) # falls foxridge als server
path=re.sub('http://content.mpiwg-berlin.mpg.de','',path) # falls content als server
path=re.sub('http://echo.mpiwg-berlin.mpg.de','',path) # falls echo
path=re.sub('http://vision.rz-berlin.mpg.de','',path) # falls vision als server
return ECHO_helpers.urlopen("http://nausikaa2.rz-berlin.mpg.de:86/cgi-bin/toc/admin/reg.cgi?path=%s"%path).readlines()
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def getTitle(self):
"""title"""
try:
return self.title.encode('utf-8','ignore')
except:
self.title=self.title.decode('iso-8859-1','ignore')[0:] #correnct conding error
return self.title.encode('utf-8','ignore')
def getLabel(self):
"""title"""
try:
return self.label.encode('utf-8','ignore')
except:
self.label=self.label.decode('iso-8859-1','ignore')[0:] #correnct conding error
return self.label.encode('utf-8','ignore')
def content_html(self):
"""template fuer content"""
return content_html(self,'resource')
def getViewClassification(self):
if hasattr(self,'viewClassification'):
return self.viewClassification
else:
return ""
def getFullTextXML(self,noredirect=None):
"""getFullTextXML; gives the FullText as an XML Document, and <error></error> if somthing goes wrong."""
try:
#zLOG.LOG("ECHO Fulltext",zLOG.INFO,"open %s"%self.metalink)
fh=ECHO_helpers.urlopen(self.metalink)
#zLOG.LOG("ECHO Fulltext",zLOG.INFO,"opened %s"%self.metalink)
dom=xml.dom.minidom.parse(fh)
texttools=dom.getElementsByTagName('texttool')
text=texttools[0].getElementsByTagName('text')
texturl=getText(text[0].childNodes)
#zLOG.LOG("ECHO Fulltext",zLOG.INFO,"found %s"%texturl)
fh.close()
#zLOG.LOG("ECHO Fulltext",zLOG.INFO,"closed fh")
#keine url
if not (texturl.split(":")[0] in ['http','ftp','file']):
if not noredirect:
return file(texturl).read()
else:
return texturl
if not noredirect:
self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
zLOG.LOG("ECHO Fulltext",zLOG.INFO,"redirect to:%s"%texturl)
self.REQUEST.RESPONSE.redirect(texturl)
else:
return texturl
except:
if not noredirect:
self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
self.REQUEST.RESPONSE.write("<error>no fulltext available</error>")
else:
return "<error>no fulltext available</error>"
def getImageView(self,noredirect=None):
"""getImages; give Imageviewr and <error></error> if somthing goes wrong."""
try:
fh=ECHO_helpers.urlopen(self.metalink)
dom=xml.dom.minidom.parse(fh)
texttools=dom.getElementsByTagName('texttool')
text=texttools[0].getElementsByTagName('image')
imagetemp=getText(text[0].childNodes)
text=dom.getElementsByTagName('archive-path')
archivepath=getText(text[0].childNodes)
archivepath=re.sub('/mpiwg/online/','',archivepath)
imageurl="http://echo.mpiwg-berlin.mpg.de/zogilib?fn="+archivepath+"/"+imagetemp
fh.close()
if not noredirect:
self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
self.REQUEST.RESPONSE.redirect(imageurl)
else:
return imageurl
except:
if not noredirect:
self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
self.REQUEST.RESPONSE.write("<error>no fulltext available</error>")
else:
return "<error>no images available</error>"
def getCopyrightsHTML(self):
"""gib (link auf copyright link, mediatyp, institution, copyrightType, label von copyrightType) aus"""
if hasattr(self,'copyrightModel'):
obj=self.copyrightModel
else:
return "ERROR"
ret=[]
for copyright in obj.getCopyrights(): #copyright - media / partner / copyrightID
try:
if hasattr(self.copyrightTypes,copyright[2]):
copyrightTypeObj=getattr(self.copyrightTypes,copyright[2])
link="copyrightTypes/"+copyright[2]+'/copyright.html'
else:
copyrightTypeObj=getattr(obj,copyright[2])
link="copyrightModel/"+copyright[2]+'/copyright.html'
label=copyrightTypeObj.label
url=getattr(copyrightTypeObj, 'url', '')
if url!='':
ret.append((url,copyright[0],copyright[1],copyright[2],label))
else:
if hasattr(copyrightTypeObj, 'copyright.html'):
ret.append(("""%s?partner=%s"""%(link,copyright[1]),copyright[0],copyright[1],copyright[2],label))
else:
ret.append(('empty',copyright[0],copyright[1],copyright[2],label))
except:
"""nothing"""
return ret
def getInstitutionsHTML(self):
"""gibt Liste der frdernden Institutionen aus"""
if hasattr(self,'support'):
obj=self.support
ret=obj.getSupporter()
return ret
else:
return ''
def getCredits(self):
"""Ausgabe der credits"""
if self.credits:
return self.credits
else:
return []
def __init__(self,id,link,metalink,resourceID,title,label,description,contentType,renderingType,copyrightType,responsible,credits,weight,coords):
self.id = id
"""Festlegen der ID"""
self.label = label
self.link= link
self.metalink=metalink
self.title=title
self.weight=weight
self.credits=toList(credits)
self.description=description
self.contentType=contentType
self.copyrightType=copyrightType
self.renderingType=renderingType
self.responsible=responsible
self.resourceID=resourceID
if coords:
coordsnew=[ string.split(x,",") for x in coords]
else:
coordsnew=[]
self.coords=coordsnew
def getCoords(self):
"""gibt coordinaten als String zurück und löscht zugleich einträge die keine Koordinaten sind, letzteres zur korrektur der Eingabe der alten version"""
retList=[]
if hasattr(self,'coords'):
for x in self.coords:
if len(x)>1:
retList.append(string.join(x,","))
return retList
def getContentType(self):
try:
return self.contentType
except:
return ""
def getCopyrightType(self):
try:
return self.copyrightType
except:
return ""
def getRenderingType(self):
try:
return self.renderingType
except:
return ""
def ECHO_resource_config(self):
"""Main configuration"""
if not hasattr(self,'weight'):
self.weight=""
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_resource.zpt').__of__(self)
return pt()
def ECHO_resource_config_main(self):
"""Main configuration"""
if not hasattr(self,'weight'):
self.weight=""
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_resource_main.zpt').__of__(self)
return pt()
def ECHO_resource_config_coords(self):
"""Coords configuration """
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_resource_coords.zpt').__of__(self)
return pt()
def ECHO_resource_config_credits(self):
"""Main configuration"""
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_resource_credits.zpt').__of__(self)
return pt()
def ECHO_resource_config_metadata(self):
"""Main configuration"""
if (hasattr(self,'metadata')) and not (hasattr(self,'metaDataHash')):
self.metaDataHash={}
self.contentType=self.bib_type
for data in self.metadata:
data_neu=re.sub('-','_',data)
self.meta
DataHash[data_neu]=getattr(self,data)[0:]
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_resource_metadata.zpt').__of__(self)
return pt()
def changeECHO_resource_main(self,metalink,link,title,label,description,contentType,renderingType,weight,resourceID,RESPONSE=None):
"""Änderung der Properties"""
self.resourceID=resourceID
self.title=title
self.label=label
self.description=description
self.contentType=contentType
self.renderingType=renderingType
self.weight=weight
self.link=link
self.metalink=metalink
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def changeECHO_resource_coords(self,coords,viewClassification,RESPONSE=None):
"""Änderung der Properties - coords"""
if type(coords)==StringType:
coords=[coords]
try:
coordsnew=[ string.split(x,",") for x in coords]
except:
coordsnew=[]
self.coords=coordsnew[0:]
self.viewClassification=viewClassification
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def changeECHO_resource_credits(self,credits,responsible,copyrightType,RESPONSE=None):
"""Änderung der Properties"""
self.credits=credits
self.responsible=responsible
self.copyrightType=copyrightType
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def changeECHO_resource_metadata_local(self,RESPONSE=None):
"""change metadata"""
tags=self.findTagsFromMapping(self.contentType)
for field in tags[1]:
self.metaDataHash[self.getFieldTag(tags,field)]=self.REQUEST.form[self.getFieldTag(tags,field)][0:]
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def changeECHO_resource_metadata(self,RESPONSE=None):
"""change metadata"""
tags=self.findTagsFromMapping(self.contentType)
self.OSAS_meta={}
for field in tags[1]:
try:
self.metaDataHash[self.getFieldTag(tags,field)]=self.REQUEST.form[self.getFieldTag(tags,field)]
self.OSAS_meta[self.getFieldTag(tags,field)]=self.REQUEST.form['OSAS_%s'%self.getFieldTag(tags,field)]
except:
"""nothing"""
ECHO_helpers.urlopen('http://xserve02.mpiwg-berlin.mpg.de:18880/echo_nav/storage/downloadExternalXML?index_meta_url=%s&xml_url=%s'%(self.metalink,self.absolute_url()+'/newMetaXML')).read()
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def getMDValue(self,fieldName):
return self.metaDataHash.get(fieldName,'!!NOT USED HERE in Type: %s'%self.contentType)
def newMetaXML(self,project=None,startpage=None,xslt=None,thumbtemplate=None,topbar=None,digiLibTemplate=None,digiliburlprefix=None):
"""new index.meta"""
self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
if not hasattr(self,'metaDataHash'):
self.copyIndex_meta2echo_resource()
try:
return writeMetadata(self.metalink,self.OSAS_meta,project,startpage,xslt,thumbtemplate,topbar,digiLibTemplate,digiliburlprefix=digiliburlprefix)
except:
return writeMetadata(self.metalink,self.metaDataHash,project,startpage,xslt,thumbtemplate,topbar,digiLibTemplate,digiliburlprefix=digiliburlprefix)
def showMetaDataXML(self,project=None,startpage=None,xslt=None,thumbtemplate=None,topbar=None,digiLibTemplate=None):
"""schreibe md"""
try:
return writeMetadata(self.metalink,self.metaDataHash,project,startpage,xslt,thumbtemplate,topbar,digiLibTemplate,xmlfrag="yes")
except:
return "<error> no metadata stored</error>"
def getMetaDataXML(self,project=None,startpage=None,xslt=None,thumbtemplate=None,topbar=None,digiLibTemplate=None):
"""prints out metadata as stored in the echo environment, format is the index.meta format"""
self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
return writeMetadata(self.metalink,self.metaDataHash)
def changeECHO_resource(self,metalink,link,title,label,description,contentType,responsible,weight,viewClassification="",coords=None,credits=None,RESPONSE=None):
"""Änderung der Properties"""
try:
coordsnew=[ string.split(x,",") for x in coords]
except:
coordsnew=[]
setECHO_collectionInformation(self,title,label,description,contentType,responsible,credits,weight,coordsnew)
self.viewClassification=viewClassification
self.coords=coordsnew[0:]
self.link=link
self.metalink=metalink
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
manage_options = Folder.manage_options+(
{'label':'Main Config','action':'ECHO_resource_config_main'},
{'label':'Change Metadata','action':'ECHO_resource_config_metadata'},
{'label':'Change Coords','action':'ECHO_resource_config_coords'},
{'label':'Add coords','action':'ECHO_graphicEntry'},
{'label':'Sync Metadata','action':'ECHO_getResourceMD'},
{'label':'Change TemplateSets and Image Viewer','action':'changeViewerTemplateSetForm'},
{'label':'set/change startpage','action':'setStartPageForm'},
{'label':'Copy MD for indexing and search','action':'copySearchFields'},
)
def getOverview(self):
"""overview graphics"""
return self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['overview'])[0][1]
def ECHO_graphicEntry(self):
"""DO nothing"""
overview = self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['overview'])
if overview:
pt=PageTemplateFile('Products/ECHO_content/zpt/ECHO_draw.zpt').__of__(self)
return pt()
else:
return "NO OVERVIEW GRAPHICS"
def ECHO_enterCoords(self,coordstr,angle="",RESPONSE=None):
"""Enter coords"""
coords=self.coords
temco=coordstr.split(",")
temco.append(angle)
coords.append(temco)
self.coords=coords[0:]
if RESPONSE is not None:
RESPONSE.redirect('ECHO_graphicEntry')
def isDefinedInThisSet(self,fields,field):
"""checks if field is defined in fields"""
if (fields[0].has_key(field)) and not (fields[0][field]==""):
return 1
else:
return 0
def getFieldLabel(self,fields,field):
"""get labels"""
try:
ret =fields[0][field]
if ret == "":
return field
else:
return ret
except:
return field
def getFieldTag(self,fields,field):
"""get labels"""
try:
ret =fields[0][field]
if ret == "":
return field
else:
return ret
except:
return field
def getFieldValue(self,field):
"""get value"""
try:
ret=self.metaDataHash[field]
if ret == "":
return None
else:
return ret
except:
return None
def getMetaDataHash(self):
"""md hash"""
return self.metaDataHash
def setFieldValue(self,field,value):
"""get value"""
if not hasattr(self,'metaDataHash'):
setattr(self,'metaDataHash',{})
self.metaDataHash[field]=value[0:]
def copySearchFields(self):
"""copys metadatafields to the object"""
fields=['author','title','year']
for field in fields:
setattr(self,'MD_'+field,self.getFieldValue(field))
def findLabelsFromMapping(self,referenceType):
"""gib hash mit label -> generic zurueck"""
#return {},[]
temp=self.ZopeFind(self.standardMD)
if referenceType=="":
referenceType="book"
bibdata={}
retdata={}
fields=[]
fieldlist=self.standardMD.fieldList
for referenceTypeF in self.referencetypes:
if referenceTypeF[1].title.lower() == referenceType.lower():
try:
bibdata[referenceTypeF[1].title]=referenceTypeF[1].fields
referenceType=referenceTypeF[1].title
except:
bibdata[referenceType]=referenceTypeF[1].fields
bibdata['data']=referenceTypeF[1]
fields=bibdata[referenceType]
for field in fieldlist:
retdata[field]=referenceTypeF[1].getValue(field)[1]
return retdata,fieldlist,temp,fields
def findTagsFromMapping(self,referenceType):
"""gib hash mit label -> generic zurueck"""
if referenceType=="":
referenceType="book"
temp = self.ZopeFind(self.standardMD)[0:]
#self.referencetypes=temp[0:]
bibdata={}
retdata={}
fieldlist=self.standardMD.fieldList
fields=[]
for referenceTypeF in temp:
#print referenceType
if referenceTypeF[1].title.lower() == referenceType.lower():
try:
bibdata[referenceTypeF[1].title]=referenceTypeF[1].fields
referenceType=referenceTypeF[1].title
except:
bibdata[referenceType]=referenceTypeF[1].fields
bibdata['data']=referenceTypeF[1]
fields=bibdata[referenceType]
for field in fieldlist:
retdata[field]=referenceTypeF[1].getValue(field)[0]
return retdata,fieldlist,temp,fields
security.declarePublic('copyIndex_meta2echo_resource') # has to be change, presentlyset because of OSAS koordination
def copyIndex_meta2echo_resource(self,RESPONSE=None):
"""copy MD von Index_meta to the echo_resource"""
(metadict, error)=readMetadata(self.metalink)
self.metaDataHash={}
if not error=="": #Fehler beim Auslesen des Metafiles
return "ERROR:",error,self.absolute_url()
self.contentType=metadict['bib_type'][0:]
fields=self.findTagsFromMapping(self.contentType)
#fields=self.findLabelsFromMapping(self.contentType)
for field in fields[1]:
if self.isDefinedInThisSet(fields,field):
#print urllib.unquote(metadict.get(self.getFieldTag(fields,field),''))
self.setFieldValue(self.getFieldTag(fields,field),metadict.get(self.getFieldTag(fields,field),''))
if RESPONSE:
return RESPONSE.redirect('manage_main')
def ECHO_getResourceMD(self,template="yes",back=None):
"""Einlesen der Metadaten und Anlegen dieser Metadaten als Informationen zur Resource"""
(metadict, error)=readMetadata(self.metalink)
if back:
self.REQUEST.SESSION['back']=back
if not error=="": #Fehler beim Auslesen des Metafiles
return "ERROR:",error
if not (metadict['bib_type'].lower()==self.contentType.lower()):
self.REQUEST.SESSION['contentStorage']=metadict['bib_type']
self.REQUEST.SESSION['contentZope']=self.contentType
return PageTemplateFile('Products/ECHO_content/zpt/ECHO_getResourceMDErrorContentType.zpt').__of__(self)()
self.REQUEST.SESSION['metadict']=metadict
self.REQUEST.SESSION['diffs']=checkDiffs(self,self.REQUEST.SESSION['metadict'])
if template=="yes":
pt=PageTemplateFile('Products/ECHO_content/zpt/ECHO_resourceMD.zpt').__of__(self)
return pt()
def ECHO_getMD(self,item):
"""Ausgabe der MD"""
return getattr(self,item)
def index_html(self):
"""standard page"""
return self.REQUEST.RESPONSE.redirect(self.link)
def startpage_html(self):
"""prints out a startpage for a resource for use e.g. in the BVE"""
# suche ob startpage.html in dem Ordner vorhanden ist, dann wir diese angezeigt
sp=self.ZopeFind(self,obj_ids=['startpage.html'])
if sp:
return sp[1]()
#prüfen ob irgendwo ein template
if hasattr(self,'startpage_index_template'):
return self.startpage_index_template()
#generisches template ausgeben
pt=PageTemplateFile('Products/ECHO_content/zpt/ECHO_startpage_index_template_standard.zpt').__of__(self)
pt.content_type="text/html"
return pt()
def toc_html(self):
sp=self.ZopeFind(self,obj_ids=['toc.html'])
if sp:
return sp[0][1]()
security.declarePublic('generate_label') # has to be change, presentlyset because of OSAS koordination
def generate_label(self):
"""Erzeugt_standard_Label aus Template"""
pt=getattr(self,"label_template_"+self.contentType.lower())
self.label=pt()[0:]
return pt()
security.declarePublic('generate_title') # has to be change, presentlyset because of OSAS koordination
def generate_title(self,RESPONSE=None):
"""Erzeugt_standard_Label aus Template"""
pt=getattr(self,"label_template_"+self.contentType.lower())
self.title=pt()[0:]
return pt()
Globals.InitializeClass(ECHO_resource)
def manage_addECHO_resourceForm(self):
"""Form for adding a ressource"""
pt=PageTemplateFile('Products/ECHO_content/zpt/AddECHO_resourceForm.zpt').__of__(self)
return pt()
def manage_addECHO_resource(self,id,title,label,description,responsible,link,metalink,weight,copyrightType=None,resourceID=None,contentType=None,renderingType=None,credits=None,coords=None,RESPONSE=None):
"""addaresource"""
newObj=ECHO_resource(id,link,metalink,resourceID,title,label,description,contentType,renderingType,copyrightType,responsible,credits,weight,coords)
self._setObject(id,newObj)
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
class ECHO_externalLink(Folder):
"""Link zu einer externen Ressource"""
security=ClassSecurityInfo()
meta_type='ECHO_externalLink'
def getTitle(self):
"""title"""
try:
return self.title.encode('utf-8','ignore')
except:
self.title=self.title.decode('iso-8859-1','ignore')[0:] #correnct conding error
return self.title.encode('utf-8','ignore')
def getLabel(self):
"""title"""
try:
return self.label.encode('utf-8','ignore')
except:
self.label=self.label.decode('iso-8859-1','ignore')[0:] #correnct conding error
return self.label.encode('utf-8','ignore')
def content_html(self):
"""template fuer content"""
return content_html(self,'externalLink')
def __init__(self,id,link,title,label,description,contentType,responsible,credits,weight,coords):
self.id = id
"""Festlegen der ID"""
self.credits=toList(credits)
self.label = label
self.link= link
self.title=title
self.weight=weight
self.description=description
self.contentType=contentType
self.responsible=responsible
coordsnew=[ string.split(x,",") for x in coords]
self.coords=coordsnew
def ECHO_externalLink_config(self):
"""Main configuration"""
if not hasattr(self,'weight'):
self.weight=""
if not hasattr(self,'coords'):
self.coords=['']
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_externalLink.zpt').__of__(self)
return pt()
def changeECHO_externalLink(self,link,title,label,description,contentType,responsible,weight,coords=None,credits=None,RESPONSE=None):
"""Änderung der Properties"""
try:
coordsnew=[ string.split(x,",") for x in coords]
except:
coordsnew=[]
setECHO_collectionInformation(self,title,label,description,contentType,responsible,credits,weight,coords)
self.coords=coordsnew[0:]
self.link=link
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
manage_options = Folder.manage_options+(
{'label':'Main Config','action':'ECHO_externalLink_config'},
)
def index_html(self):
"""standard page"""
return self.REQUEST.RESPONSE.redirect(self.link)
def manage_addECHO_externalLinkForm(self):
"""Form for external Links"""
pt=PageTemplateFile('Products/ECHO_content/zpt/AddECHO_externalLinkForm.zpt').__of__(self)
return pt()
def manage_addECHO_externalLink(self,id,title,label,description,contentType,responsible,link,weight,coords=None,credits=None,RESPONSE=None):
"""Add an external Link"""
newObj=ECHO_externalLink(id,link,title,label,description,contentType,responsible,credits,weight,coords)
self._setObject(id,newObj)
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
class ECHO_link(ECHO_externalLink):
"""external_link"""
meta_type="ECHO_link"
def content_html(self):
"""template fuer link"""
if hasattr(self,"link_template"):
return content_html(self,'link')
else:
return content_html(self,'collection')
def manage_addECHO_linkForm(self):
"""Form for external Links"""
pt=PageTemplateFile('Products/ECHO_content/zpt/AddECHO_linkForm.zpt').__of__(self)
return pt()
def manage_addECHO_link(self,id,title,label,description,contentType,responsible,link,weight,coords=None,credits=None,RESPONSE=None):
"""Add an external Link"""
newObj=ECHO_link(id,link,title,label,description,contentType,responsible,credits,weight,coords)
self._setObject(id,newObj)
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
class ECHO_collection(Folder, Persistent, Implicit, Cacheable):
"""ECHO Collection"""
security=ClassSecurityInfo()
meta_type='ECHO_collection'
viewClassificationList=viewClassificationListMaster
displayTypes=displayTypes
path="/mpiwg/online/permanent/shipbuilding"
def getRDF(self,urn=None):
"""rdf of the collection"""
contents=self.ZopeFind(self,obj_metatypes=['ECHO_group','ECHO_resource','ECHO_collection'])
ret=getRDFDescription(self,self.absolute_url(),urn=urn)
if not urn:
urn=self.absolute_url()
li="""<RDF:li RDF:resource="%s" />\n"""
for content in contents:
ret+=content[1].getRDF()+"\n"
ret+="""<RDF:Seq RDF:about="%s">\n"""%urn
for content in contents:
nurn=content[1].absolute_url()
ret+=li%nurn
return ret+"</RDF:Seq>"
def showRDF(self):
"""showrdf"""
self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
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"""
ret+=self.getRDF(urn="echo:collectionroot")+"\n"
ret+="""</RDF:RDF>"""
return ret
def changeLabels(self):
"""change form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/changeLabelsForm').__of__(self)
pt.content_type="text/html"
return pt()
def changeTitles(self):
"""change form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/changeTitleForm').__of__(self)
pt.content_type="text/html"
return pt()
def changeWeights(self):
"""change form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/changeWeightForm').__of__(self)
pt.content_type="text/html"
return pt()
def changeMetaDataLinks(self):
"""change form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/changeMetaDataLinkForm').__of__(self)
pt.content_type="text/html"
return pt()
def changeAccessRightsCollection(self):
"""change"""
ret=""
argv=self.REQUEST.form
resources=self.ZopeFind(self,obj_metatypes=['ECHO_resource'])
for resource in resources:
try:
ret+=resource[1].getId()+" "+argv[resource[1].getId()]+"</br>"
resource[1].changeAccessRightMD(argv[resource[1].getId()])
except:
"""not"""
return ret
def changeMetaDataLinkInCollection(self):
"""change all lables of a collection"""
ret=""
argv=self.REQUEST.form
resources=self.ZopeFind(self,obj_metatypes=['ECHO_resource'])
for resource in resources:
try:
ret+=resource[1].getId()+" "+argv[resource[1].getId()]+"</br>"
resource[1].metalink=argv[resource[1].getId()][0:]
except:
"""not"""
return ret
def changeMetaDataLinkInCollection(self):
"""change all lables of a collection"""
ret=""
argv=self.REQUEST.form
resources=self.ZopeFind(self,obj_metatypes=['ECHO_resource'])
for resource in resources:
try:
ret+=resource[1].getId()+" "+argv[resource[1].getId()]+"</br>"
resource[1].metalink=argv[resource[1].getId()][0:]
except:
"""not"""
return ret
def changeWeightsInCollection(self):
"""change all lables of a collection"""
ret=""
argv=self.REQUEST.form
resources=self.ZopeFind(self,obj_metatypes=['ECHO_pageTemplate','ECHO_resource','ECHO_collection','ECHO_link','ECHO_externalLink'])
for resource in resources:
try:
ret+=resource[1].getId()+" "+argv[resource[1].getId()]+"</br>"
resource[1].weight=argv[resource[1].getId()][0:]
except:
"""not"""
return ret
def changeTitlesInCollection(self):
"""change all lables of a collection"""
ret=""
argv=self.REQUEST.form
resources=self.ZopeFind(self,obj_metatypes=['ECHO_resource'])
for resource in resources:
try:
ret+=resource[1].getId()+" "+argv[resource[1].getId()]+"</br>"
resource[1].title=argv[resource[1].getId()][0:]
except:
"""not"""
return ret
def updateCollection(self,RESPONSE=None):
"""liest verzeichnisse aus dem pfad und legt sie dann als objekte in den ordner"""
files=os.listdir(self.path)
ret=""
for fileName in files:
if fileName:
tempPath=re.sub("/mpiwg/online","",self.path)
link="http://echo.mpiwg-berlin.mpg.de/zogilib_book?fn="+tempPath+"/"+fileName+"/pageimg"
metalink=self.path+"/"+fileName+"/index.meta"
try:
#link="http://nausikaa2.mpiwg-berlin.mpg.de/cgi-bin/toc/toc.x.cgi?dir="+fileName+"&step=thumb"
newObj=ECHO_resource(fileName,link,metalink,fileName,fileName,fileName,'generated','book','','','','','','')
self._setObject(fileName,newObj)
genObj=getattr(self,fileName)
#genObj.createIndexFile()
ret+="OK:"+fileName+"<br/>"
except:
print "ERROR"
ret+="ERROR:"+fileName+"<br/>"
return ret
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def updateCollectionMD(self,RESPONSE=None):
"""updateMD"""
files=os.listdir(self.path)
for fileName in files:
if fileName:
genObj=getattr(self,fileName)
genObj.copyIndex_meta2echo_resource()
genObj.generate_title()
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def changeViewerTemplateSetsForm(self):
"""change the viewer template set"""
pt=PageTemplateFile('Products/ECHO_content/zpt/changeViewerTemplateSet').__of__(self)
return pt()
def getViewerTemplateSets(self,obj_ids=None,RESPONSE=None):
"""Get the ViewerTemplateSet title for configuration"""
ret=[]
try:
viewerTemplateSets=self.ZopeFind(self.viewerTemplateSets,obj_metatypes=['OSAS_viewerTemplateSet'],obj_ids=obj_ids)#assumes viewerTemplateSets folder somewhere in the hierarchie.
for viewerTemplateSet in viewerTemplateSets:
ret.append((viewerTemplateSet[1].title,viewerTemplateSet[0],viewerTemplateSet[1]))
return ret
except:
return [('no ViewerTemplateSetfolders','')]
def getTextToolsField(self,name,default=''):
"""Lese viewerTemplateSet der Collection not implemented yet!"""
return default
def isSelectedViewerTemplateSet(self,obj,id):
"""is ausgewählt"""
if self.REQUEST['viewerTemplateSet']==id:
return 1
else:
return None
def changeViewerTemplateSets(self,project,xslt,thumbtemplate,topbar,digiLibTemplate,digiliburlprefix,RESPONSE=None):
"""change the templates"""
resources=self.ZopeFind(self,obj_metatypes=['ECHO_resource'],search_sub=1)
for resource in resources:
resource[1].changeViewerTemplateSet(project,xslt,thumbtemplate,topbar,digiLibTemplate,digiliburlprefix)
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def setStartpageFolderForm(self):
"""Form for changing the startpage"""
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_resourceStartPageFolder.zpt').__of__(self)
pt.content_type="text/html"
return pt()
def setStartpageFolder(self,startpage=None,RESPONSE=None):
"""change the templates"""
resources=self.ZopeFind(self,obj_metatypes=['ECHO_resource'],search_sub=1)
for resource in resources:
resource[1].setStartPage(startpage)
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def copyTitleToInfoXMLFolder(self,RESPONSE=None):
"""copy title into the title field of info.xml
author and date werden leer!!!
"""
resources=self.ZopeFind(self,obj_metatypes=['ECHO_resource'],search_sub=1)
for resource in resources:
ret,txt=resource[1].copyTitleToInfoXML()
if (not ret) and RESPONSE:
RESPONSE.write("error: %s\n"%txt)
if ret and RESPONSE:
RESPONSE.write("ok: %s\n"%txt)
#zLOG.LOG("ECHO (copyTitleToInfoXMLFolder)",zLOG.INFO,txt)
if RESPONSE is not None:
RESPONSE.write("done!\n")
RESPONSE.close()
RESPONSE.redirect('manage_main')
def copySearchFields(self,RESPONSE=None):
"""copys import metadatafields to the object"""
resources=self.ZopeFind(self,obj_metatypes=['ECHO_resource'])
for resource in resources:
resource[1].copySearchFields()
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def reloadMetaDataFromStorageWarning(self,RESPONSE=None):
"""warning"""
pt=PageTemplateFile('Products/ECHO_content/zpt/reloadMetaDataFromStorageWarning.zpt').__of__(self)
pt.content_type="text/html"
return pt()
def reloadMetaDataFromStorage(self,RESPONSE=None):
"""copy metadata from the storage to ECHO"""
return reloadMetaDataFromStorage(self,RESPONSE=None)
def getPartnerCopyright(self,name,sonst="generic"):
"""gibt generisches copyright eines partners aus, sonst behalte jetzige einsteillung"""
#print "hi",name,sonst
#print getattr(self.partners,name).copyrightType
try:
partner=getattr(self.partners,name)
return partner.copyrightType
except:
print "error"
return sonst
def partnerSelector_HTML(self,selected=None):
"""give type selector"""
if not selected:
retStr="<option selected>\n"
else:
retStr="<option>\n"
try: # erste version copyrightTypes exists
for partner in self.credits:
if selected and (partner==selected):
retStr+="""<option selected value="%s">%s\n"""%(partner,partner)
else:
retStr+="""<option value="%s">%s\n"""%(partner,partner)
except:
"""nothing"""
return retStr
def getViewClassification(self):
if hasattr(self,'viewClassification'):
return self.viewClassification
else:
return ""
def getTitle(self):
"""title"""
try:
return self.title.encode('utf-8','ignore')
except:
self.title=self.title.decode('iso-8859-1','ignore')[0:] #correnct conding error
return self.title.encode('utf-8','ignore')
def getLabel(self):
"""title"""
try:
return self.label.encode('utf-8','ignore')
except:
self.label=self.label.decode('iso-8859-1','ignore')[0:] #correnct conding error
return self.label.encode('utf-8','ignore')
def createRessourcesFromXMLForm(self):
"""form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/createRessourcesFromXMLForm.zpt').__of__(self)
return pt()
def createRessourcesFromXML(self,fileupload):
"""read an XML file for generating resources"""
dom=xml.dom.minidom.parse(fileupload)
ret="<h2>Added</h2>"
for resource in dom.getElementsByTagName('resource'):
link=getText(resource.getElementsByTagName('link')[0].childNodes)
label=getText(resource.getElementsByTagName('label')[0].childNodes)
#splitted=link.split("?")[0].split("/")
#id=splitted[len(splitted)-1].encode('ascii')
id=re.sub(" ","_",label).encode('ascii')
ret+="<p>"+label+"</p>"
manage_addECHO_resource(self,id,label.encode('ascii'),label.encode('ascii'),"","","",link.encode('ascii'),"","")
return ret
def getImageTag(self):
"""GetTag"""
try:
return self.imageTag
except:
return ""
def addResource(self,id,title,label,description,contentType,responsible,link,metalink,weight,credits=None,coords=None,RESPONSE=None):
"""SSS"""
try:
manage_addECHO_resource(self,id,title,label,description,responsible,link,metalink,weight,credits=None,coords=None,RESPONSE=None)
return "done"
except:
return None
def getSecondaryLink(self):
"""secondary link"""
try:
return self.secondaryLink
except:
return ""
def getSecondaryLinkTitle(self):
"""secondary link"""
try:
return self.secondaryLinkTitle
except:
return ""
def getCollectionTreeXML(self):
"""Tree as XML"""
def addPassWd(str):
"""adds a user/passwd to an url"""
txt2=re.sub(r"(http://)(.*?)","\g<1>www:3333@\g<2>",str)
return txt2
def getCollection(object,depth=0):
depth+=1
collections=""
for entry in object.__dict__.keys():
element=getattr(object,entry)
try:
if element.meta_type in ["ECHO_collection","ECHO_group"]:
collections+="<element name=\""+quote(element.title)+"\" url=\""+addPassWd(element.absolute_url())+"\">"
collections+=getCollection(element,depth)+"</element>\n"
except:
"""nothing"""
return collections
ret="""<?xml version="1.0" encoding="utf-8" ?>"""
return ret+"<collection>"+getCollection(self)+"</collection>"
def createJavaScript(self):
"""OLD CreateJava"""
ret=javaScriptMain
dynamical="\n"
for ob in self.getGraphicCoords():
if ob[4][4] == "":
dynamical+="""Coords.push(new Coord('%s', Img, %s));\n"""%(ob[1],ob[0])
else:
dynamical+="""Coords.push(new Coord('%s', Img, %s));//%s\n"""%(ob[1],ob[0],ob[4][4])
dynamical+="ShowArrow(new getObj('i.%s'),Img,%s);\n"%(ob[1],ob[0])
ret+=javaHandler%dynamical
return ret
def createJSAreas(self):
"""create area calls for JavaScript"""
dynamical="\n"
for ob in self.getGraphicCoords():
if ob[5] == "area":
dynamical+="""addArea('%s', 'overview', %s, 'area');\n"""%(ob[1],ob[0])
else:
dynamical+="""addArea('%s', 'overview', %s, 'arrow');\n"""%(ob[1],ob[0])
return dynamical
def createMapHead(self):
"""create javascript include and script tags for head"""
pt=PageTemplateFile(os.path.join(package_home(globals()), 'zpt/ECHO_content_map_frag_js')).__of__(self)
return pt()
def createMapImg(self):
"""generate img-tag for map"""
bt = BrowserCheck(self)
tag = ""
src = self.REQUEST['URL1'] + "/overview"
if bt.isN4:
tag += '<ilayer id="overview" visibility="show"><img src="%s"></ilayer>'%src
else:
tag += '<img id="overview" src="%s" />'%src
return tag
def createMapLink(self, ob, text=None):
"""generate map link"""
bt = BrowserCheck(self)
id = ob[1]
link = ob[1]
if text == None:
text = ob[2]
tag = ""
if bt.isN4:
tag += '<ilayer id="a.%s"><a onmouseover="highlightPair(\'%s\', true)" onmouseout="highlightPair(\'%s\', false)" href="%s" target="_blank"'%(id,id,id,link)
tag += ">" + text + "</a></ilayer>"
else:
tag = '<a id="a.%s" onmouseover="highlightPair(\'%s\', true)" onmouseout="highlightPair(\'%s\', false)" href="%s" target="_blank"'%(id,id,id,link)
if ob[3].contentType == 'text-popup':
tag += ' title="%s"'%ob[3].description
tag += ">" + text + "</a>"
return tag
def createMapAux(self, ob, arrowsrc="http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler/?dw=15&fn=icons/pfeil"):
"""generate map link image, text and other stuff"""
id = ob[1]
link = ob[1]
vtype = ob[5]
ctype = ob[3].contentType
bt = BrowserCheck(self)
tag = ""
if bt.isN4:
tag += '<layer id="i.%s" onmouseover="highlightPair(\'%s\', true)" onmouseout="highlightPair(\'%s\', false)">'%(id,id,id)
if vtype == "view point":
rot = ob[4][4]
tag += '<a href="%s"><img border="0" src="%s&rot=%s" /></a>'%(link,arrowsrc,rot)
else:
tag += '<a href="%s"><img border="0" width="1000" height="1000" src="trans_img"'%(link)
if ctype == "text-popup":
desc = ob[3].description
tag += ' alt="%s"'%desc
tag += ' /></a>'
tag += '</layer>'
else:
tag = '<a id="b.%s" onmouseover="highlightPair(\'%s\', true)" onmouseout="highlightPair(\'%s\', false)" href="%s" target="_blank">'%(id,id,id,link)
if vtype == "view point":
rot = ob[4][4]
if bt.isIEWin and bt.versIE > 5:
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,arrowsrc,rot,arrowsrc,rot)
else:
tag += '<img id="i.%s" src="%s&rot=%s" border="1" style="position:absolute; top:-100px; left:-100px; border-style:none;" />'%(id,arrowsrc,rot)
else:
if bt.isIEWin:
tag += '<div id="i.%s" style="position:absolute; top:-100px; left:-100px;background:url(area_img)"'%(id)
else:
tag += '<div id="i.%s" style="position:absolute; top:-100px; left:-100px;"'%(id)
if ctype == "text-popup":
desc = ob[3].description
tag += ' title="%s"'%desc
tag += '> </div>'
tag += '</a>'
return tag
security.declarePublic('getCreditObject')
def getCreditObject(self,name):
"""credit id to credititem"""
try:
return getattr(self.partners,name)
except:
return ""
security.declarePublic('ECHO_generateNavBar')
def ECHO_generateNavBar(self):
"""Erzeuge Navigationsbar"""
link=""
object="self"
ret=[]
path=self.getPhysicalPath()
for element in path:
if not element=="":
object+="."+element
label=eval(object).label
link+="/"+element
if not label=="":
ret.append((label,link))
return ret
security.declarePublic('ECHO_rerenderLinksMD')
def ECHO_rerenderLinksMDWarning(self):
"""change form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/rerenderLinksWarning').__of__(self)
pt.content_type="text/html"
return pt()
def ECHO_rerenderLinksMD(self,obj=None,types=['title','label']):
"""Rerender all Links"""
return ECHO_rerenderLinksMD(self,obj,types)
security.declarePublic('ECHO_newViewerLink')
def getCoords(self):
try:
x= [string.join(x,",") for x in self.coords]
return x
except:
return []
def __init__(self,id,title,label,description,contentType,responsible,credits,weight,sortfield,coords,secondaryLinkTitle,secondaryLink,imageTag="",bgcolour=""):
self.id = id
"""Festlegen der ID"""
self.credits=toList(credits)
self.label = label
self.title=title
self.description=description
self.contentType=contentType
self.responsible=responsible
self.imageTag=imageTag
self.weight=weight
self.sortfield=sortfield
coordsnew=[ string.split(x,",") for x in coords]
self.coords=coordsnew
self.secondaryLinkTitle=secondaryLinkTitle
self.secondaryLink=secondaryLink
self.bgcolour=bgcolour
manage_options = Folder.manage_options+ Cacheable.manage_options+(
{'label':'Main Config','action':'ECHO_collection_config'},
{'label':'Change Labels','action':'changeLabels'},
{'label':'Change Titles','action':'changeTitles'},
{'label':'Change Weights','action':'changeWeights'},
{'label':'Rerender Labels and Titles','action':'ECHO_rerenderLinksMDWarning'},
{'label':'Graphics','action':'ECHO_graphicEntry'},
{'label':'create resources from XML','action':'createRessourcesFromXMLForm'},
{'label':'Set Startpage','action':'setStartpageFolderForm'},
{'label':'Change Viewer Templates and Image Viewer','action':'changeViewerTemplateSetsForm'},
{'label':'Reload Metadata','action':'reloadMetaDataFromStorageWarning'},
{'label':'ImportCollection','action':'updateCollection'},
{'label':'Copy MD for indexing and search','action':'copySearchFields'},
)
def getOverview(self):
"""overview graphics"""
return self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['overview'])[0][1]
def ECHO_graphicEntry(self):
"""DO nothing"""
overview = self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['overview'])
if overview:
pt=PageTemplateFile('Products/ECHO_content/zpt/ECHO_draw.zpt').__of__(self)
return pt()
else:
return "NO OVERVIEW GRAPHICS"
def ECHO_enterCoords(self,coordstr,angle="",RESPONSE=None):
"""Enter coords"""
coords=self.coords
temco=coordstr.split(",")
temco.append(angle)
coords.append(temco)
self.coords=coords[0:]
if RESPONSE is not None:
RESPONSE.redirect('ECHO_graphicEntry')
security.declarePublic('ECHO_collection_config')
def ECHO_collection_config(self):
"""Main configuration"""
if not hasattr(self,'weight'):
self.weight=""
if not hasattr(self,'sortfield'):
self.sortfield="weight"
if not hasattr(self,'coords'):
self.coords=[]
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_collection.zpt').__of__(self)
return pt()
security.declarePublic('changeECHO_collection')
def getBgcolour(self):
"""colour"""
if hasattr(self,'bgcolour') and not (self.bgcolour==""):
return self.bgcolour
else:
return "#dddddd"
def changeECHO_collection(self,title,label,description,contentType,responsible,weight,secondaryLink,secondaryLinkTitle,credits=None,sortfield="weight",coords=None,RESPONSE=None,imageTag="",bgcolour="",viewClassification=None,location=None,isAlwaysClickable=None):
"""Aenderung der Properties"""
self.secondaryLink=secondaryLink
self.secondaryLinkTitle=secondaryLinkTitle
self.imageTag=imageTag
self.bgcolour=bgcolour
self.viewClassification=viewClassification
self.location=location
self.isAlwaysClickable=isAlwaysClickable
if coords:
coordsnew=[ string.split(x,",") for x in coords]
self.coords=coordsnew[0:]
else:
coordsnew=None
self.coords=None
setECHO_collectionInformation(self,title,label,description,contentType,responsible,credits,weight,coordsnew)
try:
self.coords=coordsnew[0:] # HACK fehler in setECHO_collection
except:
"""none"""
self.sortfield=sortfield
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def setAlwaysClickable(self,flag="yes"):
"""set clickable"""
if flag=="yes":
self.isAlwaysClickable="yes"
else:
self.isAlwaysClickable=None
return flag
def showOverview(self):
"""overview"""
if 'ECHO_overview.html' in self.__dict__.keys():
return getattr(self,'ECHO_overview.html')()
pt=PageTemplateFile('Products/ECHO_content/zpt/ECHO_content_overview.zpt').__of__(self)
return pt()
security.declareProtected('View','index_html')
def index_html(self):
"""standard page"""
if self.ZCacheable_isCachingEnabled():
result = self.ZCacheable_get()
if result is not None:
# Got a cached value.
return result
if 'index.html' in self.__dict__.keys():
ret=getattr(self,'index.html')()
elif 'overview' in self.__dict__.keys():
ret=self.showOverview()
elif hasattr(self,'collection_index_template'):
ret=self.collection_index_template()
elif hasattr(self,'main_index_template'):
ret=self.main_index_template()
else:
pt=PageTemplateFile('Products/ECHO_content/zpt/ECHO_main_index_template_standard.zpt').__of__(self)
pt.content_type="text/html"
ret=pt.render()
self.ZCacheable_set(ret)
return ret
def content_html(self):
"""template fuer content"""
return content_html(self,'collection')
def getCredits(self):
"""Ausgabe der credits"""
if self.credits:
return self.credits
else:
return []
def area_img(self):
"""area image"""
bt = BrowserCheck(self)
if bt.isIE or bt.isN4:
return sendFile(self, 'images/red.gif', 'image/gif')
else:
return sendFile(self, 'images/reda.png', 'image/png')
def trans_img(self):
"""empty image"""
return sendFile(self, 'images/trans.gif', 'image/gif')
def hl_lib_js(self):
"""javascript"""
return sendFile(self, 'js/hl_lib.js', 'text/plain')
def js_lib_js(self):
"""javascript"""
return sendFile(self, 'js/js_lib.js', 'text/plain')
def getGraphicCoords(self):
"""Give list of coordinates"""
subColTypes=['ECHO_collection','ECHO_resource']
ids=[]
for entrySearch in self.ZopeFind(self,obj_metatypes=subColTypes):
object=entrySearch[1]
if hasattr(object,'coords'):
for coordtemp in object.coords:
if len(coordtemp)>3:
coord=coordtemp[0:4]
label=""
vc=""
if hasattr(object,'label') and not object.label=="":
label=object.label
elif hasattr(object,'title') and not object.title=="":
label=object.title
else:
label=object.getId()
if object.viewClassification != "":
vc=object.viewClassification
else:
if len(coordtemp) > 4 and coordtemp[4] != "":
vc="view point"
else:
vc="area"
ids.append([string.join(coord,", "),object.getId(),label,object,coordtemp,vc])
return ids
getSubCols = ECHO_helpers.getSubCols
Globals.InitializeClass(ECHO_collection)
def manage_addECHO_collectionForm(self):
"""Add collection form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/AddECHO_collectionForm.zpt').__of__(self)
return pt()
def manage_addECHO_collection(self,id,title,label,description,contentType,responsible,weight,sortfield,coords="",secondaryLinkTitle="",secondaryLink="",credits=None,RESPONSE=None,imageTag="",bgcolour=""):
"""add a echo collection"""
newObj=ECHO_collection(id,title,label,description,contentType,responsible,credits,weight,sortfield,coords,secondaryLinkTitle=secondaryLinkTitle,secondaryLink=secondaryLink,imageTag=imageTag,bgcolour="")
self._setObject(id,newObj)
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
class ECHO_group(ECHO_collection):
"""ECHO Gruppe"""
security=ClassSecurityInfo()
meta_type="ECHO_group"
manage_options = Folder.manage_options+(
{'label':'Main Config','action':'ECHO_group_config'},
{'label':'Rerender Links','action':'ECHO_rerenderLinksMDWarning'},
{'label':'Graphics','action':'ECHO_graphicEntry'},
)
security.declareProtected('View','index_html')
def showRDF(self):
"""showrdf"""
self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
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"""
ret+=self.getRDF(urn="echo:collectionroot")+"\n"
ret+="""</RDF:RDF>"""
return ret
def getRDF(self,urn=None):
"""rdf of the collection"""
contents=self.ZopeFind(self,obj_metatypes=['ECHO_group','ECHO_resource','ECHO_collection'])
ret=getRDFDescription(self,self.absolute_url(),urn=urn)
if not urn:
urn=self.absolute_url()
li="""<RDF:li RDF:resource="%s" />\n"""
for content in contents:
ret+=content[1].getRDF()+"\n"
ret+="""<RDF:Seq RDF:about="%s">\n"""%urn
for content in contents:
nurn=content[1].absolute_url()
ret+=li%nurn
return ret+"</RDF:Seq>"
def index_html(self):
"""standard page"""
displayedObjects=self.ZopeFind(self,obj_metatypes=displayTypes)
#if (len(displayedObjects)==1) and (displayedObjects[0][1].meta_type=="ECHO_collection"): # nur ein Object dann redirect auf dieses Object
# return self.REQUEST.RESPONSE.redirect(displayedObjects[0][1].absolute_url())
if 'index.html' in self.__dict__.keys():
return getattr(self,'index.html')()
elif 'overview' in self.__dict__.keys():
return self.showOverview()
elif hasattr(self,'group_index_template'):
return self.group_index_template()
elif hasattr(self,'collection_index_template'):
return self.collection_index_template()
elif hasattr(self,'main_index_template'):
return self.main_index_template()
pt=PageTemplateFile('Products/ECHO_content/zpt/ECHO_main_index_template_standard.zpt').__of__(self)
pt.content_type="text/html"
return pt()
def ECHO_group_config(self):
"""Main configuration"""
if not hasattr(self,'weight'):
self.weight=""
if not hasattr(self,'sortfield'):
self.sortfield="weight"
if not hasattr(self,'coords'):
self.coords=[]
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_group.zpt').__of__(self)
return pt()
def changeECHO_group(self,title,label,description,contentType,responsible,weight,secondaryLink,secondaryLinkTitle,credits=None,sortfield="weight",coords=None,RESPONSE=None,imageTag="",bgcolour="",logo=""):
"""Änderung der Properties"""
self.secondaryLink=secondaryLink
self.secondaryLinkTitle=secondaryLinkTitle
self.imageTag=imageTag
self.bgcolour=bgcolour
self.logo=logo
if coords:
coordsnew=[ string.split(x,",") for x in coords]
self.coords=coordsnew[0:]
else:
coordsnew=None
self.coords=None
setECHO_collectionInformation(self,title,label,description,contentType,responsible,credits,weight,coordsnew)
self.sortfield=sortfield
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def getLogo(self):
"""logo ausgeben"""
try:
return self.logo
except:
return "ECHO_groups"
def content_html(self):
"""template fuer content"""
return content_html(self,'group')
def manage_addECHO_groupForm(self):
"""Add group form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/AddECHO_groupForm.zpt').__of__(self)
return pt()
def manage_addECHO_group(self,id,title,label,description,contentType,responsible,weight,sortfield,coords="",secondaryLinkTitle="",secondaryLink="",credits=None,RESPONSE=None,imageTag="",bgcolour="",logo=""):
"""add a echo group"""
newObj=ECHO_group(id,title,label,description,contentType,responsible,credits,weight,sortfield,coords,secondaryLinkTitle=secondaryLinkTitle,secondaryLink=secondaryLink,imageTag=imageTag,bgcolour="")
setattr(newObj,'logo',logo)
self._setObject(id,newObj)
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
Globals.InitializeClass(ECHO_group)
class ECHO_userFolder(UserFolder):
"""User folder for Intranet"""
_domain_auth_mode=1 # Identification via domain
meta_type="ECHO_userFolder"
def authenticate(self, name, password, request):
emergency = self._emergency_user
if name is None:
return None
if emergency and name==emergency.getUserName():
user = emergency
else:
user = self.getUser(name)
if user is not None and user.authenticate(password, request):
return user
else:
return None
def domainSpecMatch(self,spec, request):
host=''
addr=''
# Fast exit for the match-all case
if len(spec) == 1 and spec[0] == '*':
return 1
if request.has_key('REMOTE_HOST'):
host=request['REMOTE_HOST']
if request.has_key('REMOTE_ADDR'):
addr=request['REMOTE_ADDR']
if request.has_key('HTTP_X_FORWARDED_FOR'):
addr=request['HTTP_X_FORWARDED_FOR']
if not host and not addr:
return 0
if not host:
try: host=socket.gethostbyaddr(addr)[0]
except: pass
if not addr:
try: addr=socket.gethostbyname(host)
except: pass
_host=host.split('.')
_addr=addr.split('.')
_hlen=len(_host)
_alen=len(_addr)
for ob in spec:
sz=len(ob)
_ob=ob.split('.')
_sz=len(_ob)
mo = addr_match(ob)
if mo is not None:
if mo.end(0)==sz:
fail=0
for i in range(_sz):
a=_addr[i]
o=_ob[i]
if (o != a) and (o != '*'):
fail=1
break
if fail:
continue
return 1
mo = host_match(ob)
if mo is not None:
if mo.end(0)==sz:
if _hlen < _sz:
continue
elif _hlen > _sz:
_item=_host[-_sz:]
else:
_item=_host
fail=0
for i in range(_sz):
h=_item[i]
o=_ob[i]
if (o != h) and (o != '*'):
fail=1
break
if fail:
continue
return 1
return 0
Globals.default__class_init__(ECHO_userFolder)
def manage_addECHO_userFolder(self,dtself=None,REQUEST=None,**ignored):
"""add a user folder """
f=ECHO_userFolder()
self=self.this()
try: self._setObject('acl_users', f)
except: return MessageDialog(
title ='Item Exists',
message='This object already contains a User Folder',
action ='%s/manage_main' % REQUEST['URL1'])
self.__allow_groups__=f
if REQUEST is not None:
REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')
def manage_addECHO_userFolderForm(self):
"""add a user folder form"""
return manage_addECHO_userFolder(self)
def createNode(self,descrs,node):
name=descrs[node]['name']
type=descrs[node]['type']
urn=node
#print " will create",node.encode('utf-8')
id=re.sub('[^a-zA-Z0-9]','',name).encode('ascii','ignore')
#print "id",id
#print type
#self.REQUEST.RESPONSE.write("<p>%s<p>\n"%id)
if type=="CDLI_group":
try:
manage_addECHO_collection(self,id,name,name,"","","","","")
except:
self.REQUEST.RESPONSE.write("<p>Error%s</p>\n"%id)
self.REQUEST.RESPONSE.write("<p>Creates:%s</p>\n"%getattr(self,id).absolute_url())
return type,getattr(self,id),urn
if type=="CDLI_item":
try:
manage_addECHO_resource(self,id,name,name,"","",urn,"","")
except:
self.REQUEST.RESPONSE.write("<p>Error%s</p>\n"%id)
self.REQUEST.RESPONSE.write("<p>Creates:%s</p>\n"%getattr(self,id).absolute_url())
return "XX"
class ECHO_root(Folder,Persistent,Implicit):
"""ECHO Root Folder"""
security=ClassSecurityInfo()
meta_type="ECHO_root"
###CDLI adds -> have to be removed
def getTablet(self,item):
#print "getTablet"
try:
read=urllib.urlopen("http://enlil.museum.upenn.edu/cgi-bin/cdlget.plx?item=%s&project=ncdl"%item).read()
read=re.sub("\[search\]","search",read)
return read[read.find("<body>")+6:read.rfind("</body>")]
except:
return "<h1>Sorry no connection to the data server enlil.museum.upenn.edu</h1>"
#return "http://enlil.museum.upenn.edu/cgi-bin/cdlget.plx?item=%s&project=ncdl"
###END CDLI add
def sendForm(self,fromaddr,content,server='mail.mpiwg-berlin.mpg.de'):
"""sendform"""
toaddrs=["dwinter@mpiwg-berlin.mpg.de"]
msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n"
% (fromaddr, ", ".join(toaddrs),"testsub"))
server = smtplib.SMTP(server)
#server.set_debuglevel(1)
msg=msg+content
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
def generateFromRDFForm(self):
"""change form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/generateFromRDFForm').__of__(self)
pt.content_type="text/html"
return pt()
def generateFromRDF(self,file,startNode="/Cuneiform Corpus"):
"""generate from RDF"""
global seqs
seqs={}
global descrs
descrs={}
global key
key=""
global value
value=""
def getEdges(seqs,urn):
"""edges"""
ret=[]
return seqs[urn]
def createSubs(self,seqs,descrs,urn,level=0):
"""create subs"""
for edge in getEdges(seqs,urn):
cn=createNode(self,descrs,edge)
if cn[0]=="CDLI_group":
createSubs(cn[1],seqs,descrs,cn[2],level+1)
return
def start_element(name,attrs):
global seqs
global descrs
global key
global value
seq=""
if name=="RDF:Seq":
key=attrs.get('RDF:about')
try: # teste ob liste
x=seqs[key][0]
except:
seqs[key]=[]
elif name=="RDF:Description":
key=attrs.get('RDF:about')
elif name=="RDF:li":
name=attrs.get('RDF:resource')
seqs[key].append(name)
elif name=="ECHONAVIGATION:type":
value="type"
elif name=="ECHONAVIGATION:name":
value="name"
elif name=="ECHONAVIGATION:linkClickable":
value="linkClickable"
def end_element(name):
"""nothing"""
key=""
value=""
def char_data(data):
"""nothing"""
data=re.sub("\n","",data)
try:
if descrs[key].has_key(value):
descrs[key][value]+=data
else:
descrs[key][value]=data
except:
descrs[key]={}
descrs[key][value]=data
p = xml.parsers.expat.ParserCreate()
p.StartElementHandler = start_element
p.EndElementHandler = end_element
p.CharacterDataHandler = char_data
p.ParseFile(file)
self.REQUEST.RESPONSE.write("<html><body><h1>Start</h1>")
createSubs(self,seqs,descrs,startNode)
self.REQUEST.RESPONSE.write("<h1>done</h1></body></html>")
#print "done"
return "done"
def changeWeightsInCollection(self):
"""change all lables of a collection"""
ret=""
argv=self.REQUEST.form
resources=self.ZopeFind(self,obj_metatypes=['ECHO_resource','ECHO_collection','ECHO_link','ECHO_externalLink'])
for resource in resources:
try:
ret+=resource[1].getId()+" "+argv[resource[1].getId()]+"</br>"
resource[1].weight=argv[resource[1].getId()][0:]
except:
"""not"""
return ret
def changeWeights(self):
"""change form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/changeWeightForm').__of__(self)
pt.content_type="text/html"
return pt()
getSubCols = ECHO_helpers.getSubCols
manage_options=Folder.manage_options+(
{'label':'Main Config','action':'ECHO_copyright_configForm'},
{'label':'Reload Metadata','action':'reloadMetaDataFromStorageWarning'},
{'label':'Change Weights','action':'changeWeights'},
{'label':'Generate from RDF','action':'generateFromRDFForm'},
)
def showRDF(self):
"""showrdf"""
self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
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"""
ret+=self.getRDF(urn="echo:collectionroot")+"\n"
ret+="""</RDF:RDF>"""
return ret
def reloadMetaDataFromStorageWarning(self,RESPONSE=None):
"""warning"""
pt=PageTemplateFile('Products/ECHO_content/zpt/reloadMetaDataFromStorageWarning.zpt').__of__(self)
pt.content_type="text/html"
return pt()
def reloadMetaDataFromStorage(self,RESPONSE=None):
"""reload MD from Storage"""
return reloadMetaDataFromStorage(self,RESPONSE)
def getRDF(self,urn=None):
"""rdf of the collection"""
contents=self.ZopeFind(self,obj_metatypes=['ECHO_group','ECHO_resource','ECHO_collection'])
ret=getRDFDescription(self,self.absolute_url(),urn=urn)
li="""<RDF:li RDF:resource="%s" />\n"""
for content in contents:
ret+=content[1].getRDF()+"\n"
ret+="""<RDF:Seq RDF:about="%s">\n"""%urn
for content in contents:
nurn=content[1].absolute_url()
ret+=li%nurn
return ret+"</RDF:Seq>"
def showContent(self,path):
"""return content/html"""
return ECHO_helpers.urlopen(path+"/content_html").read()
def getImageViewers(self):
"""images"""
viewers=self.ZopeFind(self.standardImageViewer,obj_metatypes=['OSAS_ViewerObject'])
return viewers
def getBibTag(self,tag,content):
"""get field tag für index-meta-generation"""
if not content or content=="":
return ""
ret="<%s>"%tag
#ret+=urllib.quote(content)
ret+=content
ret+="</%s>"%tag
return ret
def getValueFromClass(self,field,found):
"""retattribute falss existing"""
try:
return getattr(found,field).decode('ascii','ignore')
except:
return ""
def getImageTag(self):
"""needed by main_template"""
return ""
secondaryLink="" #needed by main_template
secondaryLinkTitle="" #needed by main_template
def getBgcolour(self):
"""hack"""
return "#dddddd"
def contentTypeSelector_HTML(self,selected=None):
"""give type selector"""
if not selected:
retStr="<option selected>\n"
else:
retStr="<option>\n"
try: # erste version contentTypes exists
for contentType in self.ZopeFind(self.contentTypes,obj_metatypes=["ECHO_contentType","OSAS_MetadataMapping"]):
if selected and (contentType[0]==selected):
retStr+="""<option selected value="%s">%s\n"""%(contentType[0],contentType[0])
else:
retStr+="""<option value="%s">%s\n"""%(contentType[0],contentType[0])
except:
try:
for contentType in self.ZopeFind(self.standardMD,obj_metatypes=["OSAS_MetadataMapping"]):
if selected and (contentType[0]==selected):
retStr+="""<option selected value="%s">%s\n"""%(contentType[0],contentType[0])
else:
retStr+="""<option value="%s">%s\n"""%(contentType[0],contentType[0])
except:
"""nothing"""
return retStr
def renderingTypeSelector_HTML(self,selected=None):
"""give type selector"""
if not selected:
retStr="<option selected>\n"
else:
retStr="<option>\n"
try: # erste version renderingTypes exists
for renderingType in self.ZopeFind(self.renderingTypes,obj_metatypes=["ECHO_renderingType"]):
if selected and (renderingType[0]==selected):
retStr+="""<option selected value="%s">%s\n"""%(renderingType[0],renderingType[0])
else:
retStr+="""<option value="%s">%s\n"""%(renderingType[0],renderingType[0])
except:
"""nothing"""
return retStr
def renderingTypeSelector_HTML(self,selected=None):
"""give type selector"""
if not selected:
retStr="<option selected>\n"
else:
retStr="<option>\n"
try: # erste version renderingTypes exists
for renderingType in self.ZopeFind(self.renderingTypes,obj_metatypes=["ECHO_renderingType"]):
if selected and (renderingType[0]==selected):
retStr+="""<option selected value="%s">%s\n"""%(renderingType[0],renderingType[0])
else:
retStr+="""<option value="%s">%s\n"""%(renderingType[0],renderingType[0])
except:
"""nothing"""
return retStr
def copyrightTypeSelector_HTML(self, object=None, selected=None,first=None):
"""give type selector"""
if not first:
if not selected:
retStr="<option selected>\n"
else:
retStr="<option>\n"
else:
if not selected:
retStr="""<option selected value="%s">%s\n"""%first
else:
retStr="""<option value="%s">%s\n"""%first
try: # erste version copyrightTypes exists
for copyrightType in self.ZopeFind(self.copyrightTypes,obj_metatypes=["ECHO_copyrightType"]):
if selected and (copyrightType[0]==selected):
retStr+="""<option selected value="%s">%s\n"""%(copyrightType[0],copyrightType[0])
else:
retStr+="""<option value="%s">%s\n"""%(copyrightType[0],copyrightType[0])
for copyrightTypeSelf in self.ZopeFind(object,obj_metatypes=["ECHO_copyrightType"],search_sub=1):
if selected and (copyrightTypeSelf[0]==selected):
retStr+="""<option selected value="%s">%s\n"""%(copyrightTypeSelf[0],copyrightTypeSelf[0])
else:
retStr+="""<option value="%s">%s\n"""%(copyrightTypeSelf[0],copyrightTypeSelf[0])
except:
"""nothing"""
return retStr
def partnerSelector_HTML(self,selected=None):
"""give type selector"""
if not selected:
retStr="<option selected>\n"
else:
retStr="<option>\n"
try: # erste version copyrightTypes exists
for copyrightType in self.ZopeFind(self.partners,obj_metatypes=["ECHO_partner"]):
if selected and (copyrightType[0]==selected):
retStr+="""<option selected value="%s">%s\n"""%(copyrightType[0],copyrightType[0])
else:
retStr+="""<option value="%s">%s\n"""%(copyrightType[0],copyrightType[0])
except:
"""nothing"""
return retStr
mediaTypes=['all','text','images','sound','video'] # konfigurierbar in neuer version über echoroot??
def mediaTypeSelector_HTML(self,selected=None):
"""give type selector"""
if not selected:
retStr="<option selected>\n"
else:
retStr="<option>\n"
try: # erste version mediatypesTypes exists
for mediaType in self.mediaTypes:
if selected and (mediaType in selected):
retStr+="""<option selected value="%s">%s\n"""%(mediaType,mediaType)
else:
retStr+="""<option value="%s">%s\n"""%(mediaType,mediaType)
except:
"""nothing"""
return retStr
def patchContentType(self,obj=None):
"""austauschen content_type with contentType (patch bei umstieg von alter Version)"""
if not obj:
obj = self
entries=obj.ZopeFind(obj,obj_metatypes=['ECHO_resource','ECHO_collection','ECHO_externalLink','ECHO_pageTemplate'])
for entry in entries:
setattr(entry[1],'contentType',entry[1].content_type)
#entry[1].contentType == entry[1].content_type
if entry[1].meta_type == 'ECHO_collection':
entry[1].patchContentType(entry[1])
return "changed all contenttypes in: "+self.title
def patchViewClassification(self,obj=None):
"""setze viewClassification heuristisch"""
def checkIfArrow(obj):
if hasattr(obj,'coords'):
for coordtemp in obj.coords:
if (len(coordtemp)>4) and not (coordtemp[4]==''):
return 4
return None
return None
if not obj:
obj = self
entries=obj.ZopeFind(obj,obj_metatypes=['ECHO_resource','ECHO_collection','ECHO_group'])
for entry in entries:
if checkIfArrow(entry[1]):
setattr(entry[1],'viewClassification','view point')
else:
setattr(entry[1],'viewClassification','area')
#entry[1].contentType == entry[1].content_type
if entry[1].meta_type in ['ECHO_collection','ECHO_group']:
entry[1].patchViewClassification(entry[1])
return "changed all contenttypes in: "+self.title
def deleteCache(self,obj=None,RESPONSE=None):
"""setze alle collections auf cache = CacheManager"""
if not obj:
obj = self
entries=obj.ZopeFind(obj,search_sub=1)
for entry in entries:
if hasattr(entry[1],'_v_hash'):
entry[1]._v_hash=None
return "changed all CM in: "+self.title
def ECHO_newViewerLink(self,obj=None):
"""change links (:86 faellt weg)"""
if not obj:
obj = self
entries=obj.ZopeFind(obj,obj_metatypes=['ECHO_resource','ECHO_collection'])
for entry in entries:
if entry[1].meta_type == 'ECHO_resource':
entry[1].link=re.sub('\:86','',entry[1].link)
else:
entry[1].ECHO_newViewerLink(entry[1])
return "Rerenderd all links to resources in: "+self.title
def __init__(self,id,title):
"""init"""
self.id = id
self.title=title
def deleteSpace(self,str):
"""delete space at the end of a line"""
if str[len(str)-1]==" ":
return str[0:len(str)-1]
else:
return str
# zusaetliche methoden fuer das vlp muessen in ein eigenes produkt
def formatAscii(self,str,url=None):
"""ersetze ascii umbrueche durch <br>"""
#url=None
if url:
retStr=""
words=str.split("\n")
for word in words:
strUrl=url%word
retStr+="""<a href="%s">%s</a><br/>"""%(strUrl,word)
str=retStr
if str:
return re.sub(r"[\n]","<br/>",str)
else:
return ""
def link2html(self,str):
"""link2html fuer VLP muss hier noch raus"""
if str:
str=re.sub("\&","&",str)
dom=xml.dom.minidom.parseString("<?xml version='1.0' encoding='utf-8'?><txt>"+str+"</txt>")
links=dom.getElementsByTagName("link")
for link in links:
link.tagName="a"
ref=link.getAttribute("ref")
pn=link.getAttribute("page")
if self.checkRef(ref):
if pn:
link.setAttribute("href",self.aq_parent.absolute_url()+"/vlp_coll?id="+ref+"&p="+pn)
else:
link.setAttribute("href",self.aq_parent.absolute_url()+"/vlp_coll?id="+ref)
newxml=dom.toxml('utf-8')
retStr=regexpTXT.search(newxml)
return retStr.group(1)
return ""
def xml2html(self,str,quote="yes"):
"""link2html fuer VLP muss hier noch raus"""
if str:
if quote=="yes2":
str=re.sub("\&","&",str)
#dom=xml.dom.minidom.parseString(str)
dom = NonvalidatingReader.parseString(str,"http://www.mpiwg-berlin.mpg.de/")
#links=dom.getElementsByTagName("link")
links=Ft.Xml.XPath.Evaluate(".//link", contextNode=dom)
for link in links:
#link.tagName="a"
ref=link.getAttributeNS(EMPTY_NAMESPACE,"ref")
pn=link.getAttributeNS(EMPTY_NAMESPACE,"page")
cns=link.childNodes[0:]
newLink=dom.createElementNS(EMPTY_NAMESPACE,"a")
for x in cns:
newLink.appendChild(x)
link.parentNode.replaceChild(newLink,link)
if self.checkRef(ref):
if pn:
newLink.setAttributeNS(EMPTY_NAMESPACE,"href",self.aq_parent.absolute_url()+"/vlp_coll?id="+ref+"&p="+pn)
else:
newLink.setAttributeNS(EMPTY_NAMESPACE,"href",self.aq_parent.absolute_url()+"/vlp_coll?id="+ref)
#str= dom.toxml('utf-8')
buf = cStringIO.StringIO()
PrettyPrint(dom, stream=buf, encoding='UTF-8')
str = buf.getvalue()
buf.close()
#str=PrettyPrint(dom.documentElement,encoding='UTF-8')
#print link.toxml('utf-8')
#print type(str)
retStr=regexpPage.search(str)
try: # hack warum fehtl manchmal page??
return retStr.group(1)
except:
return str
return ""
def checkRef(self,ref):
if ref[0:3]=='lit':
if len(self.library_data({ 'id':ref}))>0:
return 1
try:
if ref[0:7]=="tec_cat":
return 1
except:
"""nothing"""
dbs={'vl_technology':'','vl_people':'','vl_sites':''}
res=None
for db in dbs.keys():
res=res or self.search(var=str("select reference from %s where reference =\'%s\' %s"%(db,ref,dbs[db])))
return res
#Ende Methode fuer vlp
def PgQuoteString(self,string):
"""Quote string"""
return libpq.PgQuoteString(string)
def getPartners(self):
"""Get list of Partners. Presently only from a subfolder partners"""
return [ item[1] for item in self.partners.ZopeFind(self.partners,obj_metatypes=['ECHO_partner'])]
def getInstitutions(self):
"""Get list of Partners. Presently only from a subfolder partners"""
return [ item[1] for item in self.institutions.ZopeFind(self.institutions,obj_metatypes=['ECHO_institution'])]
def getPartnersXML(self):
"""partner liste als xml"""
partners=self.getPartners()
ret="""<?xml version="1.0" encoding="utf-8" ?>
<partners>"""
for partner in partners:
ret+="""<partner id="%s" title="%s"/>\n"""%(partner.getId(),partner.title)
return ret+"\n</partners>"
def getCollectionTree(self):
"""get the collection tree (list of triples (parent,child, depth)"""
def getCollection(object,depth=0):
depth+=1
collections=[]
for entry in object.__dict__.keys():
element=getattr(object,entry)
try:
if element.meta_type=="ECHO_collection":
collections.append((object,element,depth))
collections+=getCollection(element,depth)
except:
"""nothing"""
return collections
return getCollection(self)
def getCollectionTreeIds(self):
"""Show the IDs of the Tree"""
ret=[]
for collection in self.getCollectionTree():
ret.append((collection[0].getId(),collection[1].getId(),collection[2]))
return ret
def getResourcesHTML(self,viewerType=None,filter=None):
"""gebe all ressourcen aus"""
def sortHTML(x,y):
return cmp(x[1].title,y[1].title)
ret="""<html><body><h2>Resources in ECHO</h3>"""
resources = self.ZopeFind(self,obj_metatypes=['ECHO_resource'],search_sub=1)
ret+="""<h3>Found %i resources</h3>"""%len(resources)
resources.sort(sortHTML)
for resource in resources:
echo_url=resource[1].absolute_url()
if hasattr(resource[1],'title'):
title=resource[1].title
else:
title="None"
if filter:
if re.search(filter,title):
ret+="""\n<p><a href="%s">%s</a></p>"""%(echo_url,title)
else:
ret+="""\n<p><a href="%s">%s</a></p>"""%(echo_url,title)
ret +="""\n</body></html>"""
#self.REQUEST.RESPONSE.setHeader("Content-Type", "text/html")
#self.REQUEST.RESPONSE.write(ret)
return ret
def getResourcesXML(self,viewerType=None,filter=None):
"""gebe all ressourcen aus"""
ret="""<?xml version="1.0" ?>
<index>"""
for resource in self.ZopeFind(self,obj_metatypes=['ECHO_resource'],search_sub=1):
echo_url=resource[1].absolute_url()
if hasattr(resource[1],'link'):
viewer_url=resource[1].link
else:
viewer_url="NO URL"
if filter:
if re.search(filter,viewer_url):
ret+="""\n<resource echoLink="%s" viewerLink="%s"/>"""%(urllib.quote(echo_url,safe='/:?'),urllib.quote(viewer_url,safe='/:?'))
else:
ret+="""\n<resource echoLink="%s" viewerLink="%s"/>"""%(urllib.quote(echo_url,safe='/:?'),urllib.quote(viewer_url,safe='/:?'))
ret +="""\n</index>"""
self.REQUEST.RESPONSE.setHeader("Content-Type", "text/xml")
self.REQUEST.RESPONSE.write(ret)
def getFullTextsXML(self,viewerType=None,filter=None):
"""gebe all ressourcen aus"""
ret="""<?xml version="1.0" ?>
<index>"""
for resource in self.ZopeFind(self,obj_metatypes=['ECHO_resource'],search_sub=1):
echo_url=resource[1].absolute_url()
if resource[1].getFullTextXML(noredirect="yes"):
if hasattr(resource[1],'link'):
viewer_url=echo_url+"/getFullTextXML"
else:
viewer_url="NO URL"
if filter:
if re.search(filter,viewer_url):
ret+="""\n<resource echoLink="%s" viewerLink="%s"/>"""%(urllib.quote(echo_url,safe='/:?'),urllib.quote(viewer_url,safe='/:?'))
else:
ret+="""\n<resource echoLink="%s" viewerLink="%s"/>"""%(urllib.quote(echo_url,safe='/:?'),urllib.quote(viewer_url,safe='/:?'))
ret +="""\n</index>"""
self.REQUEST.RESPONSE.setHeader("Content-Type", "text/xml")
self.REQUEST.RESPONSE.write(ret)
def getMetaDatasXML(self,viewerType=None,filter=None):
"""gebe all ressourcen aus"""
# check if the request's host part was OK
http_host = self.REQUEST['HTTP_HOST']
host_port = self.REQUEST['SERVER_PORT']
fix_host = None
if http_host and http_host.rfind(host_port) == -1:
print "HTTP_HOST needs fixing!"
fix_host = http_host + ":" + host_port
ret="""<?xml version="1.0" ?>
<index>"""
for resource in self.ZopeFind(self,obj_metatypes=['ECHO_resource'],search_sub=1):
echo_url=resource[1].absolute_url()
if fix_host:
#print "replacing ", http_host, " by ", fix_host
echo_url = string.replace(echo_url, http_host, fix_host, 1)
if hasattr(resource[1],'link'):
meta_url=echo_url+"/getMetaDataXML"
else:
meta_url="NO_URL"
if filter and not re.search(filter,viewer_url):
continue
#modificationDate=time.strptime(str(resource[1].bobobase_modification_time()),"%Y/%m/%d %H:%M:%S %Z")
modificationDate=resource[1].bobobase_modification_time().strftime("%Y/%m/%d %H:%M:%S")
ret+="""\n<resource resourceLink="%s" metaLink="%s" modificationDate="%s"/>"""%(urllib.quote(echo_url,safe='/:?'),urllib.quote(meta_url,safe='/:?'),modificationDate)
ret +="""\n</index>"""
self.REQUEST.RESPONSE.setHeader("Content-Type", "text/xml")
self.REQUEST.RESPONSE.write(ret)
def findPartners(self):
"""find all partners in partners"""
par=self.ZopeFind(self.partners, obj_metatypes='ECHO_partner')
return par
def getPartnerFromID(self):
"""find partner form ID return object"""
pa=self.REQUEST['partner']
par=self.ZopeFind(self.partners, obj_ids=[pa])
return par
def getPartnerFromIDParameter(self, id):
""" find partners from ID"""
par=self.ZopeFind(self.partners, obj_ids=[id])
return par
def getInstitutionFromID(self,id):
""" find institution from id """
inst=self.ZopeFind(self.institutions, obj_ids=[id])
return inst
def manage_addECHO_root(self,id,title,RESPONSE=None):
"""Add an ECHO_root"""
self._setObject(id,ECHO_root(id,title))
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def manage_addECHO_rootForm(self):
"""Nothing yet"""
pt=PageTemplateFile('Products/ECHO_content/zpt/AddECHO_root.zpt').__of__(self)
return pt()
class ECHO_copyrightType(Folder):
"""copyright typ"""
meta_type="ECHO_copyrightType"
def __init__(self,id,title,label,url):
"""init"""
self.id=id
self.title=title
self.label=label
self.url=url
manage_options = Folder.manage_options+(
{'label':'Main Config','action':'ECHO_copyrightType_config_mainForm'},
)
def ECHO_copyrightType_config_mainForm(self):
"""change form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_copyrightType').__of__(self)
pt.content_type="text/html"
return pt()
def ECHO_copyrightType_config_main(self,title,label,url,RESPONSE=None):
"""change"""
self.title=title
self.label=label
self.url=url
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def manage_addECHO_copyrightTypeForm(self):
"""Form for adding a ressource"""
pt=PageTemplateFile('Products/ECHO_content/zpt/AddECHO_copyrightTypeForm.zpt').__of__(self)
return pt()
def manage_addECHO_copyrightType(self,id,title,label,url,RESPONSE=None):
"""addaresource"""
newObj=ECHO_copyrightType(id,title,label,url)
self._setObject(id,newObj)
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
class ECHO_partner(Image,Persistent):
"""ECHO Partner"""
meta_type="ECHO_partner"
def __init__(self, id, title,url, file, copyrightType, person, email, country, color, content_type='', precondition=''):
self.__name__=id
self.title=title
self.url=url
self.person=person
self.email=email
self.country=country
self.color=color
self.precondition=precondition
self.copyrightType=copyrightType
data, size = self._read_data(file)
content_type=self._get_content_type(file, data, id, content_type)
self.update_data(data, content_type, size)
manage_options = Image.manage_options+(
{'label':'Partner Information','action':'ECHO_partner_config'},
)
def changeECHO_partner(self,url,copyrightType,person, email, country, color, RESPONSE=None):
"""Change main information"""
self.url=url
self.person=person
self.email=email
self.country=country
self.color=color
self.copyrightType=copyrightType
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def ECHO_partner_config(self):
"""Main configuration"""
if not hasattr(self,'url'):
self.url=""
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_partner.zpt').__of__(self)
return pt()
manage_addECHO_partnerForm=DTMLFile('dtml/ECHO_partnerAdd',globals(),
Kind='ECHO_partner',kind='ECHO_partner')
def manage_addECHO_partner(self, id, url, person, email, country, color, file=None, copyrightType='', title='', precondition='', content_type='',
REQUEST=None):
"""
Add a new ECHO_partner object.
Creates a new ECHO_partner object 'id' with the contents of 'file'.
Based on Image.manage_addImage
"""
id=str(id)
title=str(title)
content_type=str(content_type)
precondition=str(precondition)
id, title = OFS.Image.cookId(id, title, file)
self=self.this()
# First, we create the image without data:
self._setObject(id, ECHO_partner(id,title,url,'',copyrightType, person, email, country, color, content_type, precondition))
# Now we "upload" the data. By doing this in two steps, we
# can use a database trick to make the upload more efficient.
if file:
self._getOb(id).manage_upload(file)
if content_type:
self._getOb(id).content_type=content_type
if REQUEST is not None:
try: url=self.DestinationURL()
except: url=REQUEST['URL1']
REQUEST.RESPONSE.redirect('%s/manage_main' % url)
return id
class ECHO_linkList(ZopePageTemplate):
"""LinkList Objekt"""
meta_type="ECHO_linkList"
_default_content_fn = os.path.join(package_home(globals()), 'html/ECHO_pageTemplateDefault.html')
manage_options = ZopePageTemplate.manage_options+(
{'label':'Main Config','action':'changeECHO_linkListWeightForm'},
)
def content_html(self):
"""content_html"""
return content_html(self,'pageTemplate')
def changeECHO_linkListWeightForm(self):
"""change"""
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_linkListTemplate.zpt').__of__(self)
return pt()
def changeECHO_linkListWeight(self,contentType,label,RESPONSE=None):
"""change"""
self.contentType=contentType
self.label=label
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def getLabel(self):
if hasattr(self,'label'):
return self.label.encode('utf-8')
else:
return 0
def getcontentType(self):
"""get contentType"""
if hasattr(self,'contentType'):
return self.contentType
else:
return 0
def __init__(self, id, label, title=None, text=None, contentType=None):
self.id = str(id)
self.title=title
self.label=label
self.ZBindings_edit(self._default_bindings)
if text is None:
text = ''
self.pt_edit(text, contentType)
def manage_addECHO_linkListForm(self):
"""Form for adding"""
pt=PageTemplateFile('Products/ECHO_content/zpt/AddECHO_linkListTemplate.zpt').__of__(self)
return pt()
from urllib import quote
def manage_addECHO_linkList(self, id, label,contentType=0,title=None, text=None,
REQUEST=None, submit=None):
"""Add a LinkList with optional file content."""
id = str(id)
if REQUEST is None:
self._setObject(id, ECHO_linkList(id, label, text))
ob = getattr(self, id)
setattr(ob,'contentType',contentType)
if title:
ob.pt_setTitle(title)
return ob
else:
file = REQUEST.form.get('file')
headers = getattr(file, 'headers', None)
if (headers is None) or (not file.filename):
zpt = ECHO_linkList(id, file)
else:
zpt = ECHO_linkList(id, label,'', file, headers.get('contentType'))
self._setObject(id, zpt)
ob = getattr(self, id)
if title:
ob.pt_setTitle(title)
try:
u = self.DestinationURL()
except AttributeError:
u = REQUEST['URL1']
if submit == " Add and Edit ":
u = "%s/%s" % (u, quote(id))
REQUEST.RESPONSE.redirect(u+'/manage_main')
return ''
class ECHO_support(Folder):
"""gefrdert durch"""
meta_type="ECHO_support"
def __init__(self,id,institutions=None):
"""init"""
self.id=id
self.title=''
self.institutions=toList(institutions)
def getSupporter(self):
"""return institutions"""
if self.institutions:
return self.institutions
else:
return []
manage_options = Folder.manage_options+(
{'label':'Main Config','action':'ECHO_support_configForm'},
)
def ECHO_support_configForm(self):
"""change form"""
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_support').__of__(self)
pt.content_type="text/html"
return pt()
def ECHO_support_config(self,institutions=None,RESPONSE=None):
"""change"""
self.institutions=toList(institutions)
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def manage_addECHO_supportForm(self):
"""Form for adding"""
pt=PageTemplateFile('Products/ECHO_content/zpt/AddECHO_support.zpt').__of__(self)
return pt()
def manage_addECHO_support(self, id,institutions=None,RESPONSE=None):
"""add the copyright"""
meta_type="ECHO_support"
self._setObject(id, ECHO_support(id,institutions))
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
class ECHO_institution(Image,Persistent):
"""ECHO Institution"""
meta_type="ECHO_institution"
def __init__(self, id, title,url, file, person, email, country, content_type='', precondition=''):
self.__name__=id
self.title=title
self.url=url
self.person=person
self.email=email
self.country=country
self.precondition=precondition
data, size = self._read_data(file)
content_type=self._get_content_type(file, data, id, content_type)
self.update_data(data, content_type, size)
manage_options = Image.manage_options+(
{'label':'Institution Information','action':'ECHO_institution_config'},
)
def changeECHO_institution(self,url,person, email, country,RESPONSE=None):
"""Change main information"""
self.url=url
self.person=person
self.email=email
self.country=country
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def ECHO_institution_config(self):
"""Main configuration"""
if not hasattr(self,'url'):
self.url=""
pt=PageTemplateFile('Products/ECHO_content/zpt/ChangeECHO_institution.zpt').__of__(self)
return pt()
manage_addECHO_institutionForm=DTMLFile('dtml/ECHO_institutionAdd',globals(),
Kind='ECHO_institution',kind='ECHO_institution')
def manage_addECHO_institution(self, id, url, person, email, country, file=None, title='', precondition='', content_type='',
REQUEST=None):
"""
Add a new ECHO_institution object.
Creates a new ECHO_institution object 'id' with the contents of 'file'.
Based on Image.manage_addImage
"""
id=str(id)
title=str(title)
content_type=str(content_type)
precondition=str(precondition)
id, title = OFS.Image.cookId(id, title, file)
self=self.this()
# First, we create the image without data:
self._setObject(id, ECHO_institution(id,title,url,'', person, email, country, content_type, precondition))
# Now we "upload" the data. By doing this in two steps, we
# can use a database trick to make the upload more efficient.
if file:
self._getOb(id).manage_upload(file)
if content_type:
self._getOb(id).content_type=content_type
if REQUEST is not None:
try: url=self.DestinationURL()
except: url=REQUEST['URL1']
REQUEST.RESPONSE.redirect('%s/manage_main' % url)
return id
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>