File:  [Repository] / ECHO_content / ECHO_xslt.py
Revision 1.12: download - view: text, annotated - select for diffs - revision graph
Wed Oct 11 16:55:26 2006 UTC (17 years, 8 months ago) by dwinter
Branches: MAIN
CVS tags: HEAD
pagelink added in echo_languate / echo_xslt

    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:            
  141:             return self.root[name].get(pn,None)
  142:         
  143: 
  144: class ECHO_xslt(ECHO_pageTemplate,ECHO_language.ECHO_language):
  145:     """ECHO_xslt classe"""
  146: 
  147:     meta_type="ECHO_xslt"
  148:     
  149:     cache=ECHO_cache() # cache for analysed pages
  150:     caching="yes"
  151:     
  152:     appendQueryString=True # add query string to the cgiUrl can be changed with addChanges
  153:     
  154:     passURL=False #use url from querystring parameter fn to retrieve the text and not the url in cgi-url can be changed with addChanges
  155:         
  156:     
  157:     results={}
  158:     manage_options=ECHO_pageTemplate.manage_options+(
  159:      {'label':'Change xml-ressource','action':'change_ECHO_xsltForm'},)
  160:      
  161:     def refreshTxt(self):
  162:         """txt fuer refresh"""
  163:         return """ 2;url=%s?repeat=%s """%(self.absolute_url(),self.threadName)
  164: 
  165:     def xslt(self):
  166:         """xslt"""
  167: 
  168:         return self.document_src()
  169: 
  170:     def change_ECHO_xsltForm(self):
  171:         """change form"""
  172:         pt=zptFile(self, 'zpt/ChangeECHO_xsltForm.zpt')
  173:         return pt()
  174: 
  175:     def addChanges(self,cgiUrl,appendQueryString=False,passURL=False,caching=False,RESPONSE=None):
  176:         """change the xslt, ueberschriebt addChanges in ECHO_PageTemplate"""
  177:     
  178:         if urlparse.urlparse(cgiUrl)[0]=="":#relative url in absolute
  179:             self.cgiUrl=urlparse.urljoin(self.absolute_url(), cgiUrl)
  180:         else:
  181:             self.cgiUrl=cgiUrl
  182:         
  183:         if appendQueryString: 
  184:             self.appendQueryString=True
  185:         else:
  186:             self.appendQueryString=False
  187:         
  188:         if passURL:
  189:             self.passURL=True
  190:         else:
  191:             self.passURL=False
  192:        
  193:         if caching:
  194:             self.caching="yes"
  195:         else:
  196:             self.caching="No"
  197:         
  198: 
  199:         if RESPONSE:
  200:             RESPONSE.redirect("manage_main")
  201:         
  202:     def index_html(self,repeat=None):
  203:         """standard ausgabe"""
  204: 
  205:         threadName=repeat
  206:         
  207:         if not threadName or threadName=="":
  208:             
  209:             #abwaertskompatibilitŠt mit altem nivht konfigurierbaren prototypen
  210:             
  211:             if getattr(self,'cgiUrl','')=='':
  212:                 self.cgiUrl="http://medea.mpiwg-berlin.mpg.de/cgi-bin/search/q1"
  213:                 
  214:             qs="%s%s"%(self.cgiUrl,self.REQUEST['QUERY_STRING'])
  215:             xsl=self.absolute_url()+"/xslt"
  216:             self._v_xmltrans=getXML().__of__(self)
  217:             #self._xmltrans.start()
  218:             thread=Thread(target=self._v_xmltrans)
  219:             thread.start()
  220:             self._v_xmltrans.set(qs,xsl,None)
  221:             self._v_xmltrans.run()
  222:             
  223:             
  224:             self.threadName=thread.getName()[0:]
  225:             wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
  226:             if wait_template:
  227:                 return wait_template[0][1]()
  228:             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','xsltWait.zpt')).__of__(self)
  229:             return pt()
  230:             #_v_xmltrans.run()
  231:         
  232:         else:
  233:             
  234:             if (self._v_xmltrans.getResult()==None):
  235: 
  236:                 wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
  237:                 if wait_template:
  238:                         return wait_template[0][1]()
  239:                 
  240:                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','xsltWait.zpt')).__of__(self)
  241:                 return pt()
  242:             else:
  243:                 return self._v_xmltrans.getResult()
  244: 
  245:     
  246:     def getText(self):
  247:         """print nur den text"""
  248:         qs,baseUri=self.getTextInput()
  249:         self.REQUEST.RESPONSE.redirect(qs)
  250: 
  251:     def deleteCache(self):
  252:         """deletefrom cache"""
  253:         fn=self.REQUEST['fn']
  254:         self.cache.deleteObject(fn)
  255:         
  256:     def getPageLex(self,_pn="1",_id=None,_caching=None):
  257:         """getpage mit lexikalischer analyse und xslt transform
  258:         if _caching=yes dann wird die lwxikalisch analysierte seite in einem cache abgespeichert
  259:         """
  260: 
  261:         if not _caching:
  262:             _caching=self.caching
  263:             
  264:         fn=self.REQUEST['fn']
  265: 
  266:         if not _id:
  267:            
  268:             fromCache=self.cache.retrieveObject(fn,_pn)
  269:      
  270:             if fromCache and _caching=="yes":
  271:               
  272:                 txt = fromCache
  273:             else:
  274:                 txt=self.tagLex(nr=_pn)   
  275:              
  276:                 self.cache.storeObject(fn,_pn,txt[0:])
  277:             
  278:         else:
  279:            txt=self.tagLex(id=_id)
  280:            
  281:         xsl=self.xslt()
  282:         
  283:         xsltproc=Processor()
  284:         if type(txt)==UnicodeType:
  285:             document = InputSource.DefaultFactory.fromString(txt.encode('utf-8'))
  286:         else:
  287:             document = InputSource.DefaultFactory.fromString(txt)
  288:         stylesheet = InputSource.DefaultFactory.fromString(xsl)
  289:         xsltproc.appendStylesheet(stylesheet)
  290:         tmp=xsltproc.run(document)
  291:         #bugfix for digilib images which doesn't accept &amp;
  292:         tmp=tmp.replace("&amp;","&")
  293:         
  294: 
  295:         return tmp[0:]
  296:             
  297:     def getTextInput(self):
  298:         """get the text
  299:         wie der text geholt wird liegt an der konfiguration,
  300:         is appendQueryString gesetzt, dann wir jeweils der Querystring an vorgebenen url gesetzt, erwartet wird fn=
  301:         fŸr den Pfad, is passURL gesetzt, dann wird falls fn= eine vollstŠndige url enthŠlt, diese anstelle der in cgiurl definierten genommen.
  302:         """
  303:         
  304:         if getattr(self,'passURL',False) and self.REQUEST.has_key('fn') and (urlparse.urlparse(self.REQUEST['fn'])[0]=='http'):
  305:             qs=self.REQUEST['fn']
  306:             baseUri=qs
  307:         elif getattr(self,'pappendQueryString',True):
  308:             qs="%s%s"%(self.cgiUrl,self.REQUEST['QUERY_STRING'])
  309:             baseUri=self.cgiUrl
  310:         else:
  311:             qs="%s"%(self.cgiUrl)
  312:             baseUri=self.cgiUrl
  313:         
  314:         #fact= InputSource.DefaultFactory.fromUri(qs)
  315:         return qs,baseUri
  316:         #return InputSource.InputSource(fact)
  317:         #xmlt=urllib.urlopen(qs).read()
  318:         
  319:     def getPage(self,_pn="-1",_id=None,REQUEST=None,_caching=None):
  320:         """get a page from an xml"""
  321:         
  322:         if not _caching:
  323:             _caching=self.caching
  324:             
  325:         pn=int(_pn)-1
  326:         if pn<0 and (not _id):
  327:             if REQUEST:
  328:                 return "Sorry, pagenumbers have to be greater than 0"
  329:             else:
  330:                 return None
  331:        
  332:         xmlt,self.baseUri=self.getTextInput()
  333:         
  334:         #get the text from cache, if existing
  335:         fromCache=self.cache.retrieveObject(self.baseUri,"-1")
  336:         if fromCache and _caching=="yes":
  337:           
  338:             txt = fromCache
  339:         else:
  340: 
  341:             txt=urllib.urlopen(xmlt).read()
  342:             
  343:             self.cache.storeObject(self.baseUri,"-1",txt)
  344:         
  345:         
  346:         dom=NonvalidatingReader.parseString(txt,self.baseUri)
  347:         
  348:         #pb should have a namespache
  349: 
  350:         pbs=dom.xpath("//mpiwg:pb",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})
  351:         
  352:         if len(pbs)==0: # versuche nochmal ohne
  353:             pbs=dom.xpath("//pb")
  354: 
  355:         if _id:
  356:             #suche wieviele pb for der id
  357:             
  358:             
  359:             idpb=dom.xpath("//*[@id='%s']/preceding::node()/mpiwg:pb"%_id,explicitNss={'html':'http://test.de','mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})
  360:             if len(idpb)==0:
  361:                 idpb=dom.xpath("//*[@id='%s']/preceding::node()/pb"%_id)
  362:          
  363:             if len(idpb)==0:
  364:                         k=0
  365:                         for node in dom.xpath("//*[@id='%s']//preceding::node()"%_id,explicitNss={'html':'http://test.de','mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
  366:                             if getattr(node,'tagName',"")=="mpiwg:pb":
  367:                                 k+=1
  368:             else:
  369:                 k=len(idpb)
  370:             pn=k-1 #-1 wegen Seitenzahlzaehlung startet mit 0
  371:             
  372:         if pn > len(pbs):
  373:             if REQUEST:
  374:                 return "Sorry, pagenumber %s does not exit"%(pn+1)
  375:             else:
  376:                 return None
  377:             
  378:         beginNode=pbs[pn] #take the n'th pb
  379: 
  380:         if not (pn==len(pbs)-1): # nicht die letzte Seite
  381:             endNode=pbs[pn+1]
  382:         else:
  383:             endNode=None
  384:         
  385:         deleteNodes=beginNode.xpath('preceding::node()')
  386:         if endNode:
  387:             deleteNodes+=endNode.xpath('following::node()')
  388:         for node in deleteNodes:
  389:             try:
  390:                 parent=node.xpath("..")
  391:            
  392:                 if parent:
  393:                     parent[0].removeChild(node)
  394:             except:
  395:                 zLOG.LOG("ECHO_Resource (getAccessRightMD)", zLOG.INFO,"%s (%s)"%sys.exc_info()[0:2])
  396:         strio = StringIO()
  397:         PrettyPrint(dom,strio) 
  398:         xmlstr = strio.getvalue()
  399:         
  400:         return xmlstr
  401: 
  402: 
  403:         
  404: def manage_addECHO_xsltForm(self):
  405:     """Form for adding"""
  406:     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','AddECHO_xslt.zpt')).__of__(self)
  407:     return pt()
  408: 
  409: from urllib import quote
  410: 
  411: 
  412: def manage_addECHO_xslt(self, id, label, weight= 0,contentType=0,title=None, text=None, cgiUrl=None,
  413:                            REQUEST=None, submit=None):
  414:     "Add a Page Template with optional file content."
  415: 
  416:     
  417:     id = str(id)
  418:     if REQUEST is None:
  419:         self._setObject(id, ECHO_xslt(id, text))
  420:         ob = getattr(self, id)
  421:         setattr(ob,'weight',weight)
  422:         setattr(ob,'label',label)
  423:         setattr(ob,'contentType',contentType)
  424:         if title:
  425:             ob.pt_setTitle(title)
  426:         return ob
  427:         setattr(ob,'cgiUrl',cgiUrl)
  428:     else:
  429:         file = REQUEST.form.get('file')
  430:         headers = getattr(file, 'headers', None)
  431:         if headers is None or not file.filename:
  432:             zpt = ECHO_xslt(id)
  433:         else:
  434:             zpt = ECHO_xslt(id, file, headers.get('contentType'))
  435: 
  436:         self._setObject(id, zpt)
  437:         ob = getattr(self, id)
  438:         setattr(ob,'weight',weight)
  439:         setattr(ob,'label',label)
  440:         setattr(ob,'cgiUrl',cgiUrl)
  441:         if title:
  442:             ob.pt_setTitle(title)
  443:         
  444:         try:
  445:             u = self.DestinationURL()
  446:         except AttributeError:
  447:             u = REQUEST['URL1']
  448: 
  449:         if submit == " Add and Edit ":
  450:             u = "%s/%s" % (u, quote(id))
  451:         REQUEST.RESPONSE.redirect(u+'/manage_main')
  452:     return ''
  453: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>