### XSLT Class ###
### setzt 4 suite vorraus ###
from Acquisition import Implicit
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Globals import DTMLFile
from ECHO_Nav import ECHO_pageTemplate
from threading import Thread,Timer
import threading
from ECHO_helpers import *
try:
from ECHO_language import *
except:
print "no echo language"
class ECHO_language:
"""leere Klasse"""
pass
import sys
import urllib
import urlparse
from Ft.Xml.Domlette import Print, PrettyPrint
from StringIO import StringIO
from types import *
from Globals import package_home
import transaction
import os.path
import urllib,cgi
import logging
try:
from Ft.Xml.Xslt.Processor import Processor
from Ft.Xml import InputSource, EMPTY_NAMESPACE,Parse
from Ft.Xml.Domlette import NonvalidatingReader
except:
print "4suite has to be installed"
class getXML(Thread):
"""get XML thread"""
def set(self,qs,xsl,result):
"""set"""
self._v_qs=qs
self.xsl=xsl
self.result=None
# def acquireLock(self):
#
# lock=getattr(self, "_v_lock", None)
# if not lock:
# self._v_lock=threading.Lock()
# lock=self._v_lock
# lock.acquire()
#
# def releaseLock(self):
# # acquire() should have been called
# # about one second before. This means the volatile lock
# # should still be there
#
# self._v_lock.release()
#
def __call__(self):
"""wait"""
self.run()
return True
def run(self):
"""call it"""
xml=""
try:
#urlH=urllib.urlopen(self._v_qs)
#xml=urlH.read()
#urlH.close()
xsltproc=Processor()
logging.debug("start XML")
document = InputSource.DefaultFactory.fromUri(self._v_qs)
stylesheet = InputSource.DefaultFactory.fromUri(self.xsl)
logging.debug("got all files XML")
xsltproc.appendStylesheet(stylesheet)
logging.debug("got all files do the transform")
#print self.xsl
#< xsltproc.run(document)
tmp=xsltproc.run(document)
self.result=tmp[0:]
except:
self.result="<html>error: %s %s<br>"%sys.exc_info()[0:2]
self.result+=xml
self.result+="</html>"
def getResult(self):
return self.result
from ZODB import DB
from ZODB.FileStorage import FileStorage
class ECHO_cache:
def __init__(self):
"""init the storage"""
try:
self.storage=FileStorage(os.path.join(INSTANCE_HOME,"var/echo_cache.fs"))
self.db=DB(self.storage)
self.connection=self.db.open()
self.root=self.connection.root()
except:
pass
def deleteObject(self,name,pn=None):
"""delete an object from cache"""
fileStore=self.root.get(name,None)
if fileStore:
if not pn:
del(self.root[name])
else:
if self.root[name].get(pn,None):
del(self.root[name][pn])
def storeObject(self,name,pn,object):
"""store an object"""
if not self.root.get(name,None):
self.root[name]={}
#following is necessary to make clear that object has really changed for ZODB
tmp=self.root[name]
tmp[pn]=object
self.root[name]=tmp
transaction.get().commit()
return True
def retrieveObject(self,name,pn):
"""retrieve it"""
fileStore=self.root.get(name,None)
if not fileStore:
return None
else:
return self.root[name].get(pn,None)
class ECHO_xslt(ECHO_pageTemplate,ECHO_language):
"""ECHO_xslt classe"""
meta_type="ECHO_xslt"
cache=ECHO_cache() # cache for analysed pages
caching="yes"
appendQueryString=True # add query string to the cgiUrl can be changed with addChanges
passURL=False #use url from querystring parameter fn to retrieve the text and not the url in cgi-url can be changed with addChanges
results={}
manage_options=ECHO_pageTemplate.manage_options+(
{'label':'Change xml-ressource','action':'change_ECHO_xsltForm'},)
def refreshTxt(self):
"""txt fuer refresh"""
return """ 2;url=%s?repeat=%s """%(self.absolute_url(),self.threadName)
def xslt(self):
"""xslt"""
return self.document_src()
def change_ECHO_xsltForm(self):
"""change form"""
pt=zptFile(self, 'zpt/ChangeECHO_xsltForm.zpt')
return pt()
def addChanges(self,cgiUrl,appendQueryString=False,passURL=False,caching=False,RESPONSE=None):
"""change the xslt, ueberschriebt addChanges in ECHO_PageTemplate"""
if urlparse.urlparse(cgiUrl)[0]=="":#relative url in absolute
self.cgiUrl=urlparse.urljoin(self.absolute_url(), cgiUrl)
else:
self.cgiUrl=cgiUrl
if appendQueryString:
self.appendQueryString=True
else:
self.appendQueryString=False
if passURL:
self.passURL=True
else:
self.passURL=False
if caching:
self.caching="yes"
else:
self.caching="No"
if RESPONSE:
RESPONSE.redirect("manage_main")
def index_html(self,repeat=None):
"""standard ausgabe"""
threadName=repeat
if not threadName or threadName=="":
# compatibility with old prototype
if getattr(self,'cgiUrl','')=='':
self.cgiUrl="http://medea.mpiwg-berlin.mpg.de/cgi-bin/search/q1"
qs="%s%s"%(self.cgiUrl,self.REQUEST['QUERY_STRING'])
xsl=self.absolute_url()+"/xslt"
#self._v_xmltrans=getXML().__of__(self)
self._v_xmltrans=getXML()
#self._xmltrans.start()
#thread=Thread(target=self._v_xmltrans)
#thread.start()
logging.debug("Thread prepared")
self._v_xmltrans.set(qs,xsl,None)
self._v_xmltrans.start()
logging.debug("Thread started")
#self.threadName=thread.getName()[0:]
self.threadName=self._v_xmltrans.getName()[0:]
wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
if wait_template:
return wait_template[0][1]()
pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','xsltWait.zpt')).__of__(self)
return pt()
#_v_xmltrans.run()
else:
if (self._v_xmltrans.getResult()==None):
wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
if wait_template:
return wait_template[0][1]()
pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','xsltWait.zpt')).__of__(self)
return pt()
else:
return self._v_xmltrans.getResult()
def getText(self):
"""print nur den text"""
qs,baseUri=self.getTextInput()
self.REQUEST.RESPONSE.redirect(qs)
def deleteCache(self):
"""deletefrom cache"""
fn=self.REQUEST['fn']
self.cache.deleteObject(fn)
def createLinkNode(self,url,dom):
"""createa a link node"""
txt=dom.createTextNode("<XMLLink>")
node=dom.createElementNS("http://test.de","a")
node.setAttributeNS("http://test.de","href",url)
node.appendChild(txt)
return node
def forwardLink(self,linkid,url,type="target",RESPONSE=None):
"""forward to link"""
if RESPONSE:
RESPONSE.redirect(self.getLink(linkid,url,type=type))
else:
return self.getLink(linkid,url,type=type)
def getLink(self,linkid,url,type="target"):
"""get target for linkid"""
dom=NonvalidatingReader.parseUri(url)
masterurl=dom.xpath("//mpiwg:masterurl/@ref",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
slaveurl=dom.xpath("//mpiwg:slaveurl/@ref",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
#check now if there are in the link file
xp="//mpiwg:link[@id='%s']"%linkid
if type=="target":
for link in dom.xpath(xp,explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
fn=link.xpath("mpiwg:target/@filename",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
if urlparse.urlparse(urllib.unquote(fn))[0]=="http": # fn ist eine url
return urllib.unquote(fn) # dann gibt diese zurueck
ref=link.xpath("mpiwg:target/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
ref2=link.xpath("mpiwg:target/mpiwg:pagelink/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
selectionNodeIndex=link.xpath("mpiwg:target/mpiwg:pagelink/@selectionNodeIndex",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
lstr=slaveurl+'fn='+fn+'&_id='+ref+'&_pagelink=%s///%s/%s/%s'%(ref2,selectionNodeIndex,linkid,'target')
lstr+="&_links="+urllib.quote(url)
else:
for link in dom.xpath(xp,explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
fn=link.xpath("mpiwg:source/@filename",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
if urlparse.urlparse(urllib.unquote(fn))[0]=="http": # fn ist eine url
return urllib.unquote(fn) # dann gibt diese zurueck
ref=link.xpath("mpiwg:source/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
ref2=link.xpath("mpiwg:source/mpiwg:pagelink/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
selectionNodeIndex=link.xpath("mpiwg:source/mpiwg:pagelink/@selectionNodeIndex",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
lstr=masterurl+'fn='+fn+'&_id='+ref+'&_pagelink=%s///%s/%s/%s'%(ref2,selectionNodeIndex,linkid,'source')
lstr+="&_links="+urllib.quote(url)
return lstr
def addLinksUrl(self,txt,url):
"""add reference to links to url"""
ret=[]
dom=NonvalidatingReader.parseUri(url)
textDom=NonvalidatingReader.parseString(txt)
#find ids in txt
ids=textDom.xpath("//*[@id]")
for textid in ids:
xp="//mpiwg:link[mpiwg:source/@refid='%s']"%textid.xpath("@id")[0].value
for link in dom.xpath(xp,explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
ref2=link.xpath("mpiwg:source/mpiwg:pagelink/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
selectionNodeIndex=link.xpath("mpiwg:source/mpiwg:pagelink/@selectionNodeIndex",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
linkid=link.xpath("@id")[0].value
ret.append('%s///%s/%s/%s'%(ref2,selectionNodeIndex,linkid,'source'))
xp="//mpiwg:link[mpiwg:target/@refid='%s']"%textid.xpath("@id")[0].value
for link in dom.xpath(xp,explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
ref2=link.xpath("mpiwg:target/mpiwg:pagelink/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
selectionNodeIndex=link.xpath("mpiwg:target/mpiwg:pagelink/@selectionNodeIndex",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
linkid=link.xpath("@id")[0].value
ret.append('%s///%s/%s/%s'%(ref2,selectionNodeIndex,linkid,'target'))
return ret
def addLinks(self,txt,url="http://127.0.0.1:8080/HFQP/linkCreator/getCollectionXML?collection=commentary2"):
"""add links to a page from xml linkfile"""
dom=NonvalidatingReader.parseUri(url)
textDom=NonvalidatingReader.parseString(txt)
#find ids in txt
ids=textDom.xpath("//*[@id]")
masterurl=dom.xpath("//mpiwg:masterurl/@ref",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
slaveurl=dom.xpath("//mpiwg:slaveurl/@ref",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
#check now if there are in the link file
for textid in ids:
xp="//mpiwg:link[mpiwg:source/@refid='%s']"%textid.xpath("@id")[0].value
for link in dom.xpath(xp,explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
fn=link.xpath("mpiwg:target/@filename",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
print fn
if urlparse.urlparse(urllib.unquote(fn))[0]=="http": # fn ist eine url
lstr=urllib.unquote(fn) # dann gibt diese zurueck
else:
try:
ref=link.xpath("mpiwg:target/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
ref2=link.xpath("mpiwg:target/mpiwg:pagelink/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
selectionNodeIndex=link.xpath("mpiwg:target/mpiwg:pagelink/@selectionNodeIndex",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
linkid=link.xpath("@id")[0].value
lstr=slaveurl+'fn='+fn+'&_id='+ref+'&_pagelink=%s///%s/%s/%s'%(ref2,selectionNodeIndex,linkid,'target')
lstr+="&_links="+urllib.quote(url)
except:
lstr=""
node=self.createLinkNode(lstr,textDom)
textid.parentNode.insertBefore(node,textid)
xp="//mpiwg:link[mpiwg:target/@refid='%s']"%textid.xpath("@id")[0].value
for link in dom.xpath(xp,explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
fn=link.xpath("mpiwg:source/@filename",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
if urlparse.urlparse(urllib.unquote(fn))[0]=="http": # fn ist eine url
lstr=urllib.unquote(fn) # dann gibt diese zurueck
else:
ref=link.xpath("mpiwg:source/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
ref2=link.xpath("mpiwg:source/mpiwg:pagelink/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
selectionNodeIndex=link.xpath("mpiwg:source/mpiwg:pagelink/@selectionNodeIndex",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
linkid=link.xpath("@id")[0].value
lstr=masterurl+'fn='+fn+'&_id='+ref+'&_pagelink=%s///%s/%s/%s'%(ref2,selectionNodeIndex,linkid,"source")
lstr+="&_links="+urllib.quote(url)
node=self.createLinkNode(lstr,textDom)
textid.parentNode.insertBefore(node,textid)
strio = StringIO()
PrettyPrint(textDom,strio)
xmlstr = strio.getvalue()
return xmlstr
def getPageLex(self,_pn="1",_id=None,_caching=None,_links=None,_showall="no",_displaylinks="yes"):
"""getpage mit lexikalischer analyse und xslt transform
if _caching=yes dann wird die lwxikalisch analysierte seite in einem cache abgespeichert
"""
def encode(hash):
ret=[]
for x in hash.keys():
value=hash[x]
if type(value) is ListType:
for z in value:
ret.append("%s=%s"%(x,z))
else:
ret.append("%s=%s"%(x,value))
return "&".join(ret)
if not _caching:
_caching=self.caching
fn=self.REQUEST['fn']
if not _id:
fromCache=self.cache.retrieveObject(fn,_pn)
if fromCache and _caching=="yes":
txt = fromCache
else:
txt=self.tagLex(nr=_pn)
self.cache.storeObject(fn,_pn,txt[0:])
else:
txt=self.tagLex(id=_id)
if _showall=="yes":
params=cgi.parse_qs(self.REQUEST['QUERY_STRING'])
params['_pagelink']=self.addLinksUrl(txt,url=_links)
params['_showall']='no'
print self.absolute_url()+"?"+encode(params)
self.REQUEST.RESPONSE.redirect(self.absolute_url()+"/getPageLex?"+encode(params))
xsl=self.xslt()
xsltproc=Processor()
if type(txt)==UnicodeType:
document = InputSource.DefaultFactory.fromString(txt.encode('utf-8'))
else:
document = InputSource.DefaultFactory.fromString(txt)
stylesheet = InputSource.DefaultFactory.fromString(xsl)
xsltproc.appendStylesheet(stylesheet)
tmp=xsltproc.run(document)
if _links and (_displaylinks=='yes'):
_links=urllib.unquote(_links)
tmp=self.addLinks(tmp,url=_links)
#bugfix for digilib images which doesn't accept &
tmp=tmp.replace("&","&")
return tmp[0:]
def getTextInput(self):
"""get the text
wie der text geholt wird liegt an der konfiguration,
is appendQueryString gesetzt, dann wir jeweils der Querystring an vorgebenen url gesetzt, erwartet wird fn=
fuer den Pfad, is passURL gesetzt, dann wird falls fn= eine vollstaendige url enthaelt, diese anstelle der in cgiurl definierten genommen.
"""
if getattr(self,'passURL',False) and self.REQUEST.has_key('fn') and (urlparse.urlparse(self.REQUEST['fn'])[0]=='http'):
qs=self.REQUEST['fn']
baseUri=qs
elif getattr(self,'pappendQueryString',True):
qs="%s%s"%(self.cgiUrl,self.REQUEST['QUERY_STRING'])
baseUri=self.cgiUrl
else:
qs="%s"%(self.cgiUrl)
baseUri=self.cgiUrl
#fact= InputSource.DefaultFactory.fromUri(qs)
return qs,baseUri
#return InputSource.InputSource(fact)
#xmlt=urllib.urlopen(qs).read()
def getPage(self,_pn="-1",_id=None,REQUEST=None,_caching=None):
"""get a page from an xml"""
if not _caching:
_caching=self.caching
pn=int(_pn)-1
if pn<0 and (not _id):
if REQUEST:
return "Sorry, pagenumbers have to be greater than 0"
else:
return None
xmlt,self.baseUri=self.getTextInput()
#get the text from cache, if existing
try:
fromCache=self.cache.retrieveObject(self.baseUri,"-1")
except:
fromCache=None
if fromCache and _caching=="yes":
txt = fromCache
else:
txt=urllib.urlopen(xmlt).read()
self.cache.storeObject(self.baseUri,"-1",txt)
dom=NonvalidatingReader.parseString(txt,self.baseUri)
#pb should have a namespache
pbs=dom.xpath("//mpiwg:pb",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})
if len(pbs)==0: # versuche nochmal ohne
pbs=dom.xpath("//pb")
if _id:
#suche wieviele pb for der id
idpb=dom.xpath("//*[@id='%s']/preceding::node()/mpiwg:pb"%_id,explicitNss={'html':'http://www.w3.org/1999/xhtml','mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})
if len(idpb)==0:
idpb=dom.xpath("//*[@id='%s']/preceding::node()/pb"%_id)
if len(idpb)==0:
k=0
for node in dom.xpath("//*[@id='%s']//preceding::node()"%_id,explicitNss={'html':'http://www.w3.org/1999/xhtml','mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
if getattr(node,'tagName',"")=="mpiwg:pb":
k+=1
else:
k=len(idpb)
#pn=k-1 #-1 wegen Seitenzahlzaehlung startet mit 0
pn=k-1 #-1 wegen Seitenzahlzaehlung startet mit 0
if pn > len(pbs):
if REQUEST:
return "Sorry, pagenumber %s does not exit"%(pn+1)
else:
return None
beginNode=pbs[pn] #take the n'th pb
if not (pn==len(pbs)-1): # nicht die letzte Seite
endNode=pbs[pn+1]
else:
endNode=None
deleteNodes=beginNode.xpath('preceding::node()')
if endNode:
deleteNodes+=endNode.xpath('following::node()')
for node in deleteNodes:
try:
parent=node.xpath("..")
if parent:
parent[0].removeChild(node)
except:
logger("ECHO_Resource (getAccessRightMD)", logging.INFO,"%s (%s)"%sys.exc_info()[0:2])
strio = StringIO()
PrettyPrint(dom,strio)
xmlstr = strio.getvalue()
return xmlstr
def manage_addECHO_xsltForm(self):
"""Form for adding"""
pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','AddECHO_xslt.zpt')).__of__(self)
return pt()
from urllib import quote
def manage_addECHO_xslt(self, id, label, weight= 0,contentType=0,title=None, text=None, cgiUrl=None,
REQUEST=None, submit=None):
"Add a Page Template with optional file content."
id = str(id)
if REQUEST is None:
self._setObject(id, ECHO_xslt(id, text))
ob = getattr(self, id)
setattr(ob,'weight',weight)
setattr(ob,'label',label)
setattr(ob,'contentType',contentType)
if title:
ob.pt_setTitle(title)
return ob
setattr(ob,'cgiUrl',cgiUrl)
else:
file = REQUEST.form.get('file')
headers = getattr(file, 'headers', None)
if headers is None or not file.filename:
zpt = ECHO_xslt(id)
else:
zpt = ECHO_xslt(id, file, headers.get('contentType'))
self._setObject(id, zpt)
ob = getattr(self, id)
setattr(ob,'weight',weight)
setattr(ob,'label',label)
setattr(ob,'cgiUrl',cgiUrl)
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 ''
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>