1: ### XSLT Class ###
2: ### setzt 4 suite vorraus ###
3: from Acquisition import Implicit
4: from Products.PageTemplates.PageTemplateFile import PageTemplateFile
5: from Globals import DTMLFile
6: from ECHO_Nav import ECHO_pageTemplate
7: from threading import Thread,Timer
8: import threading
9: from ECHO_helpers import *
10: import ECHO_language
11: import sys
12: import urllib
13: import urlparse
14: from Ft.Xml.Domlette import Print, PrettyPrint
15: from StringIO import StringIO
16: from types import *
17: from Globals import package_home
18: import transaction
19:
20: import os.path
21:
22: import urllib
23:
24: try:
25: from Ft.Xml.Xslt.Processor import Processor
26: from Ft.Xml import InputSource, EMPTY_NAMESPACE,Parse
27: from Ft.Xml.Domlette import NonvalidatingReader
28: except:
29: print "4suite has to be installed"
30:
31:
32: class getXML(Implicit):
33: """get XML thread"""
34:
35: def set(self,qs,xsl,result):
36: """set"""
37:
38: self._v_qs=qs
39: self.xsl=xsl
40: self.result=None
41:
42: # def acquireLock(self):
43: #
44: # lock=getattr(self, "_v_lock", None)
45: # if not lock:
46: # self._v_lock=threading.Lock()
47: # lock=self._v_lock
48: # lock.acquire()
49: #
50: # def releaseLock(self):
51: # # acquire() should have been called
52: # # about one second before. This means the volatile lock
53: # # should still be there
54: #
55: # self._v_lock.release()
56: #
57:
58: def __call__(self):
59: """wait"""
60: return True
61:
62: def run(self):
63: """call it"""
64: xml=""
65:
66: try:
67:
68: urlH=urllib.urlopen(self._v_qs)
69: xml=urlH.read()
70: urlH.close()
71: xsltproc=Processor()
72: document = InputSource.DefaultFactory.fromString(xml)
73:
74: stylesheet = InputSource.DefaultFactory.fromUri(self.xsl)
75:
76: xsltproc.appendStylesheet(stylesheet)
77:
78:
79: #print self.xsl
80: #print xsltproc.run(document)
81: tmp=xsltproc.run(document)
82:
83: self.result=tmp[0:]
84:
85:
86: except:
87:
88: self.result="<html>error: %s %s<br>"%sys.exc_info()[0:2]
89: self.result+=xml
90: self.result+="</html>"
91:
92:
93:
94: def getResult(self):
95:
96: return self.result
97:
98: from ZODB import DB
99: from ZODB.FileStorage import FileStorage
100: class ECHO_cache:
101: def __init__(self):
102: """init the storage"""
103: self.storage=FileStorage("/var/tmp/echo_cache.fs")
104: self.db=DB(self.storage)
105: self.connection=self.db.open()
106: self.root=self.connection.root()
107:
108: def deleteObject(self,name,pn=None):
109: """delete an object from cache"""
110: fileStore=self.root.get(name,None)
111: if fileStore:
112: if not pn:
113: del(self.root[name])
114: else:
115: if self.root[name].get(pn,None):
116: del(self.root[name][pn])
117:
118:
119: def storeObject(self,name,pn,object):
120: """store an object"""
121:
122: if not self.root.get(name,None):
123: self.root[name]={}
124:
125:
126: #following is necessary to make clear that object has really changed for ZODB
127: tmp=self.root[name]
128: tmp[pn]=object
129: self.root[name]=tmp
130: transaction.get().commit()
131: return True
132:
133: def retrieveObject(self,name,pn):
134: """retrieve it"""
135:
136: fileStore=self.root.get(name,None)
137: if not fileStore:
138: return None
139: else:
140: return self.root[name].get(pn,None)
141:
142:
143: class ECHO_xslt(ECHO_pageTemplate,ECHO_language.ECHO_language):
144: """ECHO_xslt classe"""
145:
146: meta_type="ECHO_xslt"
147:
148: cache=ECHO_cache() # cache for analysed pages
149: caching="yes"
150:
151: appendQueryString=True # add query string to the cgiUrl can be changed with addChanges
152:
153: passURL=False #use url from querystring parameter fn to retrieve the text and not the url in cgi-url can be changed with addChanges
154:
155:
156: results={}
157: manage_options=ECHO_pageTemplate.manage_options+(
158: {'label':'Change xml-ressource','action':'change_ECHO_xsltForm'},)
159:
160: def refreshTxt(self):
161: """txt fuer refresh"""
162: return """ 2;url=%s?repeat=%s """%(self.absolute_url(),self.threadName)
163:
164: def xslt(self):
165: """xslt"""
166:
167: return self.document_src()
168:
169: def change_ECHO_xsltForm(self):
170: """change form"""
171: pt=zptFile(self, 'zpt/ChangeECHO_xsltForm.zpt')
172: return pt()
173:
174: def addChanges(self,cgiUrl,appendQueryString=False,passURL=False,caching=False,RESPONSE=None):
175: """change the xslt, ueberschriebt addChanges in ECHO_PageTemplate"""
176:
177: if urlparse.urlparse(cgiUrl)[0]=="":#relative url in absolute
178: self.cgiUrl=urlparse.urljoin(self.absolute_url(), cgiUrl)
179: else:
180: self.cgiUrl=cgiUrl
181:
182: if appendQueryString:
183: self.appendQueryString=True
184: else:
185: self.appendQueryString=False
186:
187: if passURL:
188: self.passURL=True
189: else:
190: self.passURL=False
191:
192: if caching:
193: self.caching="yes"
194: else:
195: self.caching="No"
196:
197:
198: if RESPONSE:
199: RESPONSE.redirect("manage_main")
200:
201: def index_html(self,repeat=None):
202: """standard ausgabe"""
203:
204: threadName=repeat
205:
206: if not threadName or threadName=="":
207:
208: #abwaertskompatibilitt mit altem nivht konfigurierbaren prototypen
209:
210: if getattr(self,'cgiUrl','')=='':
211: self.cgiUrl="http://medea.mpiwg-berlin.mpg.de/cgi-bin/search/q1"
212:
213: qs="%s%s"%(self.cgiUrl,self.REQUEST['QUERY_STRING'])
214: xsl=self.absolute_url()+"/xslt"
215: self._v_xmltrans=getXML().__of__(self)
216: #self._xmltrans.start()
217: thread=Thread(target=self._v_xmltrans)
218: thread.start()
219: self._v_xmltrans.set(qs,xsl,None)
220: self._v_xmltrans.run()
221:
222:
223: self.threadName=thread.getName()[0:]
224: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
225: if wait_template:
226: return wait_template[0][1]()
227: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','xsltWait.zpt')).__of__(self)
228: return pt()
229: #_v_xmltrans.run()
230:
231: else:
232:
233: if (self._v_xmltrans.getResult()==None):
234:
235: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
236: if wait_template:
237: return wait_template[0][1]()
238:
239: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','xsltWait.zpt')).__of__(self)
240: return pt()
241: else:
242: return self._v_xmltrans.getResult()
243:
244:
245: def getText(self):
246: """print nur den text"""
247: qs,baseUri=self.getTextInput()
248: self.REQUEST.RESPONSE.redirect(qs)
249:
250: def deleteCache(self):
251: """deletefrom cache"""
252: fn=self.REQUEST['fn']
253: self.cache.deleteObject(fn)
254:
255: def getPageLex(self,_pn="1",_id=None,_caching=None):
256: """getpage mit lexikalischer analyse und xslt transform
257: if _caching=yes dann wird die lwxikalisch analysierte seite in einem cache abgespeichert
258: """
259:
260: if not _caching:
261: _caching=self.caching
262:
263: fn=self.REQUEST['fn']
264:
265: if not _id:
266: fromCache=self.cache.retrieveObject(fn,_pn)
267:
268: if fromCache and _caching=="yes":
269:
270: txt = fromCache
271: else:
272: txt=self.tagLex(nr=_pn)
273:
274: self.cache.storeObject(fn,_pn,txt[0:])
275:
276: else:
277: txt=self.tagLex(id=_id)
278:
279: xsl=self.xslt()
280:
281: xsltproc=Processor()
282: if type(txt)==UnicodeType:
283: document = InputSource.DefaultFactory.fromString(txt.encode('utf-8'))
284: else:
285: document = InputSource.DefaultFactory.fromString(txt)
286: stylesheet = InputSource.DefaultFactory.fromString(xsl)
287: xsltproc.appendStylesheet(stylesheet)
288: tmp=xsltproc.run(document)
289: #bugfix for digilib images which doesn't accept &
290: tmp=tmp.replace("&","&")
291: return tmp[0:]
292:
293: def getTextInput(self):
294: """get the text
295: wie der text geholt wird liegt an der konfiguration,
296: is appendQueryString gesetzt, dann wir jeweils der Querystring an vorgebenen url gesetzt, erwartet wird fn=
297: fr den Pfad, is passURL gesetzt, dann wird falls fn= eine vollstndige url enthlt, diese anstelle der in cgiurl definierten genommen.
298: """
299:
300: if getattr(self,'passURL',False) and self.REQUEST.has_key('fn') and (urlparse.urlparse(self.REQUEST['fn'])[0]=='http'):
301: qs=self.REQUEST['fn']
302: baseUri=qs
303: elif getattr(self,'pappendQueryString',True):
304: qs="%s%s"%(self.cgiUrl,self.REQUEST['QUERY_STRING'])
305: baseUri=self.cgiUrl
306: else:
307: qs="%s"%(self.cgiUrl)
308: baseUri=self.cgiUrl
309:
310: #fact= InputSource.DefaultFactory.fromUri(qs)
311: return qs,baseUri
312: #return InputSource.InputSource(fact)
313: #xmlt=urllib.urlopen(qs).read()
314:
315: def getPage(self,_pn="-1",_id=None,REQUEST=None,_caching=None):
316: """get a page from an xml"""
317:
318: if not _caching:
319: _caching=self.caching
320:
321: pn=int(_pn)-1
322: if pn<0 and (not _id):
323: if REQUEST:
324: return "Sorry, pagenumbers have to be greater than 0"
325: else:
326: return None
327:
328: xmlt,self.baseUri=self.getTextInput()
329:
330: #get the text from cache, if existing
331: fromCache=self.cache.retrieveObject(self.baseUri,"-1")
332: if fromCache and _caching=="yes":
333:
334: txt = fromCache
335: else:
336:
337: txt=urllib.urlopen(xmlt).read()
338:
339: self.cache.storeObject(self.baseUri,"-1",txt)
340:
341: dom=NonvalidatingReader.parseString(txt,self.baseUri)
342:
343: #pb should have a namespache
344:
345: pbs=dom.xpath("//mpiwg:pb",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})
346:
347: if len(pbs)==0: # versuche nochmal ohne
348: pbs=dom.xpath("//pb")
349:
350: if _id:
351: #suche wieviele pb for der id
352:
353:
354: idpb=dom.xpath("//*[@id='%s']/preceding::node()/mpiwg:pb"%_id,explicitNss={'html':'http://test.de','mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})
355: if len(idpb)==0:
356: idpb=dom.xpath("//*[@id='%s']/preceding::node()/pb"%_id)
357:
358: if len(idpb)==0:
359: k=0
360: for node in dom.xpath("//*[@id='%s']//preceding::node()"%_id,explicitNss={'html':'http://test.de','mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
361: if getattr(node,'tagName',"")=="mpiwg:pb":
362: k+=1
363: else:
364: k=len(idpb)
365: pn=k-1 #-1 wegen Seitenzahlzaehlung startet mit 0
366:
367: if pn > len(pbs):
368: if REQUEST:
369: return "Sorry, pagenumber %s does not exit"%(pn+1)
370: else:
371: return None
372:
373: beginNode=pbs[pn] #take the n'th pb
374:
375: if not (pn==len(pbs)-1): # nicht die letzte Seite
376: endNode=pbs[pn+1]
377: else:
378: endNode=None
379:
380: deleteNodes=beginNode.xpath('preceding::node()')
381: if endNode:
382: deleteNodes+=endNode.xpath('following::node()')
383: for node in deleteNodes:
384: try:
385: parent=node.xpath("..")
386:
387: if parent:
388: parent[0].removeChild(node)
389: except:
390: zLOG.LOG("ECHO_Resource (getAccessRightMD)", zLOG.INFO,"%s (%s)"%sys.exc_info()[0:2])
391: strio = StringIO()
392: PrettyPrint(dom,strio)
393: xmlstr = strio.getvalue()
394:
395: return xmlstr
396:
397:
398:
399: def manage_addECHO_xsltForm(self):
400: """Form for adding"""
401: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','AddECHO_xslt.zpt')).__of__(self)
402: return pt()
403:
404: from urllib import quote
405:
406:
407: def manage_addECHO_xslt(self, id, label, weight= 0,contentType=0,title=None, text=None, cgiUrl=None,
408: REQUEST=None, submit=None):
409: "Add a Page Template with optional file content."
410:
411:
412: id = str(id)
413: if REQUEST is None:
414: self._setObject(id, ECHO_xslt(id, text))
415: ob = getattr(self, id)
416: setattr(ob,'weight',weight)
417: setattr(ob,'label',label)
418: setattr(ob,'contentType',contentType)
419: if title:
420: ob.pt_setTitle(title)
421: return ob
422: setattr(ob,'cgiUrl',cgiUrl)
423: else:
424: file = REQUEST.form.get('file')
425: headers = getattr(file, 'headers', None)
426: if headers is None or not file.filename:
427: zpt = ECHO_xslt(id)
428: else:
429: zpt = ECHO_xslt(id, file, headers.get('contentType'))
430:
431: self._setObject(id, zpt)
432: ob = getattr(self, id)
433: setattr(ob,'weight',weight)
434: setattr(ob,'label',label)
435: setattr(ob,'cgiUrl',cgiUrl)
436: if title:
437: ob.pt_setTitle(title)
438:
439: try:
440: u = self.DestinationURL()
441: except AttributeError:
442: u = REQUEST['URL1']
443:
444: if submit == " Add and Edit ":
445: u = "%s/%s" % (u, quote(id))
446: REQUEST.RESPONSE.redirect(u+'/manage_main')
447: return ''
448:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>