File:  [Repository] / documentViewer / documentViewer.py
Revision 1.3: download - view: text, annotated - select for diffs - revision graph
Thu Apr 6 17:13:43 2006 UTC (18 years, 2 months ago) by casties
Branches: MAIN
CVS tags: HEAD
preliminary version 0.2
- lots of stuff rewritten
- new template system
- still no access control

    1: 
    2: genericDigilib="http://nausikaa2.rz-berlin.mpg.de/digitallibrary/"
    3: 
    4: from OFS.Folder import Folder
    5: from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
    6: from Products.PageTemplates.PageTemplateFile import PageTemplateFile
    7: from AccessControl import ClassSecurityInfo
    8: from Globals import package_home
    9: 
   10: from Ft.Xml.Domlette import NonvalidatingReader
   11: from Ft.Xml.Domlette import PrettyPrint, Print
   12: from Ft.Xml import EMPTY_NAMESPACE
   13: 
   14: import Ft.Xml.XPath
   15: 
   16: import os.path
   17: import cgi
   18: import urllib
   19: import zLOG
   20: 
   21: def getTextFromNode(nodename):
   22:     nodelist=nodename.childNodes
   23:     rc = ""
   24:     for node in nodelist:
   25:         if node.nodeType == node.TEXT_NODE:
   26:            rc = rc + node.data
   27:     return rc
   28: 
   29: import socket
   30: 
   31: def urlopen(url):
   32:         """urlopen mit timeout"""
   33:         socket.setdefaulttimeout(2)
   34:         ret=urllib.urlopen(url)
   35:         socket.setdefaulttimeout(5)
   36:         return ret
   37:     
   38: def getParamFromDigilib(path,param):
   39:     """gibt param von dlInfo aus"""
   40:     imageUrl=genericDigilib+"/dirInfo-xml.jsp?mo=dir&fn="+path
   41: 
   42:     zLOG.LOG("documentViewer (getparamfromdigilib)", zLOG.INFO, "dirInfo (%s) from %s"%(param,imageUrl))
   43:     
   44:     try:
   45:         dom = NonvalidatingReader.parseUri(imageUrl)
   46:     except:
   47:         return None
   48:     
   49:     params=dom.xpath("//dir/%s"%param)
   50:     zLOG.LOG("documentViewer (getparamfromdigilib)", zLOG.INFO, "dirInfo:%s"%params)
   51:     
   52:     if params:
   53:         return getTextFromNode(params[0])
   54: 
   55:     
   56: 
   57: 
   58: ##
   59: ## documentViewer class
   60: ##
   61: class documentViewer(Folder):
   62:     """document viewer"""
   63: 
   64:     meta_type="Document viewer"
   65:     
   66:     security=ClassSecurityInfo()
   67:     manage_options=Folder.manage_options+(
   68:         {'label':'main config','action':'changeDocumentViewerForm'},
   69:         )
   70: 
   71:     # templates and forms
   72:     viewer_main = PageTemplateFile('zpt/viewer_main', globals())
   73:     thumbs_main = PageTemplateFile('zpt/thumbs_main', globals())
   74:     image_main = PageTemplateFile('zpt/image_main', globals())
   75:     head_main = PageTemplateFile('zpt/head_main', globals())
   76:     docuviewer_css = PageTemplateFile('css/docuviewer.css', globals())
   77: 
   78:     security.declareProtected('View management screens','changeDocumentViewerForm')    
   79:     changeDocumentViewerForm = PageTemplateFile('zpt/changeDocumentViewer', globals())
   80: 
   81:     
   82:     def __init__(self,id,imageViewerUrl,title="",digilibBaseUrl=None):
   83:         """init document viewer"""
   84:         self.id=id
   85:         self.title=title
   86:         self.imageViewerUrl=imageViewerUrl
   87:         self.digilibBaseUrl = digilibBaseUrl
   88:         if not self.digilibBaseUrl:
   89:             self.digilibBaseUrl = self.findDigilibUrl()
   90:         # add template folder so we can always use template.something
   91:         self.manage_addFolder('template')
   92: 
   93: 
   94:     security.declareProtected('View','index_html')
   95:     def index_html(self,mode,url,start=0,pn=1):
   96:         '''
   97:         view it
   98:         @param mode: defines which type of document is behind url
   99:         @param url: url which contains display information
  100:         '''
  101:         
  102:         zLOG.LOG("documentViewer (index)", zLOG.INFO, "mode: %s url:%s start:%s pn:%s"%(mode,url,start,pn))
  103:         print "dlbaseurl:", self.digilibBaseUrl
  104:         
  105:         if not hasattr(self, 'template'):
  106:             # create template folder if it doesn't exist
  107:             print "no template folder -- creating"
  108:             self.manage_addFolder('template')
  109:             
  110:         if not self.digilibBaseUrl:
  111:             self.digilibBaseUrl = self.findDigilibUrl() or "http://nausikaa.mpiwg-berlin.mpg.de/digitallibrary"
  112:             
  113:         print "dlbaseurl:", self.digilibBaseUrl
  114: 
  115:         docinfo = self.getDocinfo(mode=mode, url=url)
  116:         pageinfo = self.getPageinfo(start=start,current=pn)
  117:         pt = getattr(self.template, 'viewer_main')
  118:         return pt(docinfo=docinfo,pageinfo=pageinfo)
  119:   
  120:   
  121:     def imageLink(self,nr):
  122:         """link hinter den images"""
  123:         paramsTmp=cgi.parse_qs(self.REQUEST['QUERY_STRING'])
  124:         params={}
  125:         for x in paramsTmp.iteritems():
  126:                 params[x[0]]=x[1][0]
  127:     
  128:         params['pn']=nr
  129:         newUrl=self.REQUEST['URL']+"?"+urllib.urlencode(params)
  130:         return newUrl
  131:         
  132:     def getStyle(self, idx, selected, style=""):
  133:         """returns a string with the given style + 'sel' if path == selected."""
  134:         #zLOG.LOG("documentViewer (getstyle)", zLOG.INFO, "idx: %s selected: %s style: %s"%(idx,selected,style))
  135:         if idx == selected:
  136:             return style + 'sel'
  137:         else:
  138:             return style    
  139: 
  140:             
  141:     def thumbruler(self,cols,rows,start,maximum):
  142:         """ruler for thumbs"""
  143:         ret=""
  144:         paramsTmp=cgi.parse_qs(self.REQUEST['QUERY_STRING'])
  145:         params={}
  146:         for x in paramsTmp.iteritems():
  147: 
  148:             if not x[0]=="start":
  149:                 params[x[0]]=x[1][0]
  150: 
  151:         newUrlSelect=self.REQUEST['URL']+"?"+urllib.urlencode(params)    
  152:         if start>0:
  153:             newStart=max(start-cols*rows,0)
  154:             params['start']=newStart
  155:             newUrl=self.REQUEST['URL']+"?"+urllib.urlencode(params)
  156:             ret+="""<a href="%s">prev</a>"""%newUrl
  157: 
  158: 
  159:         ret+="""<select onChange="location.href='%s&start='+this.options[this.selectedIndex].value">"""%newUrlSelect
  160:         nr,rest=divmod(maximum,cols*rows)
  161:         if rest > 0:
  162:             nr+=1
  163:         for i in range(nr):
  164:             nr=i*cols*rows
  165:            
  166:             if (start >= nr) and (start < nr+cols*rows):  
  167:                 ret+="""<option value="%s" selected>%s</option>"""%(nr,nr)
  168:             else:
  169:                 ret+="""<option value="%s">%s</option>"""%(nr,nr)
  170:         ret+="</select>"
  171:         
  172:         if start<maximum:
  173:             newStart=min(start+cols*rows,maximum)
  174:             params['start']=newStart
  175:             newUrl=self.REQUEST['URL']+"?"+urllib.urlencode(params)
  176:             ret+="""<a href="%s">next</a>"""%newUrl
  177:         
  178:         return ret
  179:     
  180:         
  181:         
  182:     def getBibinfoFromIndexMeta(self,path,docinfo=None,dom=None):
  183:         """gets bibliographical info from the index.meta file at url or given by dom"""
  184:         zLOG.LOG("documentViewer (getbibinfofromindexmeta)", zLOG.INFO,"path: %s"%(path))
  185:         
  186:         if docinfo is None:
  187:             docinfo = {}
  188:             
  189:         metaData=self.metadata.main.meta.bib
  190:         if dom is None:
  191:             server="http://nausikaa.mpiwg-berlin.mpg.de/digitallibrary/servlet/Texter?fn="
  192:             path="/".join(path.split("/")[0:-1])
  193:             metaUrl=server+path+"/index.meta"
  194:             try:
  195:                 dom = NonvalidatingReader.parseUri(metaUrl)
  196:             except:
  197:                 return docinfo
  198:         
  199:         type=dom.xpath("//bib/@type")
  200:         if type and (len(type)>0):
  201:             type=type[0].value
  202:         else:
  203:             type="generic"
  204:         type=type.replace("-"," ")# wrong typesiin index meta "-" instead of " "
  205:         hash=metaData.generateMappingForType(type)
  206: 
  207:         docinfo['author']=getTextFromNode(dom.xpath("//bib/%s"%hash['author'][0])[0])
  208:         docinfo['title']=getTextFromNode(dom.xpath("//bib/%s"%hash['title'][0])[0])
  209:         docinfo['year']=getTextFromNode(dom.xpath("//bib/%s"%hash['year'][0])[0])
  210:         
  211:         return docinfo
  212: 
  213:         
  214:     def getDocinfoFromTextTool(self,url,docinfo=None):
  215:        """parse texttool tag in index meta"""
  216:        zLOG.LOG("documentViewer (getdocinfofromtexttool)", zLOG.INFO,"url: %s"%(url))
  217:        if docinfo is None:
  218:            docinfo = {}
  219:            
  220:        try:
  221:            dom = NonvalidatingReader.parseUri(url)
  222:        except:
  223:            zLOG.LOG("documentViewer (parseUrlTexttool)", zLOG.INFO,"%s (%s)"%sys.exc_info()[0:2])
  224:            return docinfo
  225:        
  226:        archivePaths=dom.xpath("//resource/archive-path")
  227:        
  228:        if archivePaths and (len(archivePaths)>0):
  229:            archivePath=getTextFromNode(archivePaths[0])
  230:        else:
  231:            archivePath=None
  232:        
  233:        images=dom.xpath("//texttool/image")
  234:        
  235:        if images and (len(images)>0):
  236:            image=getTextFromNode(images[0])
  237:        else:
  238:            image=None
  239:            
  240:        if image and archivePath:
  241:            image=os.path.join(archivePath,image)
  242:            image=image.replace("/mpiwg/online",'')
  243:            pt=getParamFromDigilib(image,'size')
  244:            docinfo['imagePath'] = image
  245:            docinfo['numberOfPages'] = pt
  246:            
  247:        viewerUrls=dom.xpath("//texttool/digiliburlprefix")
  248:        
  249:        if viewerUrls and (len(viewerUrls)>0):
  250:            viewerUrl=getTextFromNode(viewerUrls[0])
  251:            docinfo['imageURL'] = viewerURL
  252:                   
  253:        textUrls=dom.xpath("//texttool/text")
  254:        
  255:        if textUrls and (len(textUrls)>0):
  256:            textUrl=getTextFromNode(textUrls[0])
  257:            docinfo['textURL'] = textURL
  258:                      
  259:        docinfo = self.getBibinfoFromIndexMeta(url,docinfo=docinfo,dom=dom)
  260:        return docinfo
  261:    
  262: 
  263:     def getDocinfoFromImagePath(self,path,docinfo=None):
  264:         """path ist the path to the images it assumes that the index.meta file is one level higher."""
  265:         zLOG.LOG("documentViewer (getdocinfofromimagepath)", zLOG.INFO,"path: %s"%(path))
  266:         if docinfo is None:
  267:             docinfo = {}
  268:         docinfo['imagePath'] = path
  269:         path=path.replace("/mpiwg/online","")
  270:         pt=getParamFromDigilib(path,'size')
  271:         docinfo['numberOfPages'] = pt
  272:         imageUrl=genericDigilib+"/servlet/Scaler?fn=%s"%path
  273:         docinfo['imageURL'] = imageUrl
  274:         
  275:         docinfo = self.getBibinfoFromIndexMeta(path,docinfo=docinfo)
  276:         return docinfo
  277:     
  278:     
  279:     def getDocinfo(self, mode, url):
  280:         """returns docinfo depending on mode"""
  281:         zLOG.LOG("documentViewer (getdocinfo)", zLOG.INFO,"mode: %s, url: %s"%(mode,url))
  282:         # look for cached docinfo in session
  283:         if self.REQUEST.SESSION.has_key('docinfo'):
  284:             docinfo = self.REQUEST.SESSION['docinfo']
  285:             # check if its still current
  286:             if docinfo is not None and docinfo.get('mode') == mode and docinfo.get('url') == url:
  287:                 zLOG.LOG("documentViewer (getdocinfo)", zLOG.INFO,"docinfo in session: %s"%docinfo)
  288:                 return docinfo
  289:         # new docinfo
  290:         docinfo = {'mode': mode, 'url': url}
  291:         if mode=="texttool": #index.meta with texttool information
  292:             docinfo = self.getDocinfoFromTextTool(url, docinfo=docinfo)
  293:         elif mode=="imagepath":
  294:             docinfo = self.getDocinfoFromImagePath(url, docinfo=docinfo)
  295:         else:
  296:             zLOG.LOG("documentViewer (getdocinfo)", zLOG.ERROR,"unknown mode!")
  297:         zLOG.LOG("documentViewer (getdocinfo)", zLOG.INFO,"docinfo: %s"%docinfo)
  298:         self.REQUEST.SESSION['docinfo'] = docinfo
  299:         return docinfo
  300:         
  301:         
  302:     def getPageinfo(self, start, current):
  303:         """returns pageinfo with the given parameters"""
  304:         pageinfo = {}
  305:         pageinfo['start'] = start
  306:         pageinfo['current'] = current
  307:         return pageinfo
  308:                 
  309:     def text(self,mode,url,pn):
  310:         """give text"""
  311:         if mode=="texttool": #index.meta with texttool information
  312:             (viewerUrl,imagepath,textpath)=parseUrlTextTool(url)
  313:         
  314:         print textpath
  315:         try:
  316:             dom = NonvalidatingReader.parseUri(textpath)
  317:         except:
  318:             return None
  319:     
  320:         list=[]
  321:         nodes=dom.xpath("//pb")
  322: 
  323:         node=nodes[int(pn)-1]
  324:         
  325:         p=node
  326:         
  327:         while p.tagName!="p":
  328:             p=p.parentNode
  329:         
  330:         
  331:         endNode=nodes[int(pn)]
  332:         
  333:         
  334:         e=endNode
  335:         
  336:         while e.tagName!="p":
  337:             e=e.parentNode
  338:         
  339:         
  340:         next=node.parentNode
  341:         
  342:         #sammle s
  343:         while next and (next!=endNode.parentNode):
  344:             list.append(next)    
  345:             next=next.nextSibling    
  346:         list.append(endNode.parentNode)
  347:         
  348:         if p==e:# beide im selben paragraphen
  349:             pass
  350: #    else:
  351: #            next=p
  352: #            while next!=e:
  353: #                print next,e
  354: #                list.append(next)
  355: #                next=next.nextSibling
  356: #            
  357: #        for x in list:
  358: #            PrettyPrint(x)
  359: #
  360: #        return list
  361: #
  362: 
  363:     def image(self,mode,url,pn):
  364:         """give image out"""
  365:         if mode=="texttool": #index.meta with texttool information
  366:             (viewerUrl,imagepath,textpath)=parseUrlTextTool(url)
  367:             if not viewerUrl:
  368:                 viewerUrl=self.imageViewerUrl
  369:             url=viewerUrl+"pn=%s&fn=%s"%(pn,imagepath[0])
  370:             ret="""<iframe height="100%%" width="100%%" src="%s"/>"""%url
  371:             return url
  372:         elif mode=="imagepath":
  373:             url=url.replace("/mpiwg/online","")
  374:             url=self.imageViewerUrl+"pn=%s&fn=%s"%(pn,url)
  375:             ret="""<iframe height="100%%" width="100%%" src="%s"/>"""%url
  376:             return url
  377:             
  378:         
  379:     def findDigilibUrl(self):
  380:         """try to get the digilib URL from zogilib"""
  381:         url = self.imageViewerUrl[:-1] + "/getScalerUrl"
  382:         try:
  383:             scaler = urlopen(url).read()
  384:             return scaler.replace("/servlet/Scaler?", "")
  385:         except:
  386:             return None
  387:     
  388:     def changeDocumentViewer(self,imageViewerUrl,title="",digilibBaseUrl=None,RESPONSE=None):
  389:         """init document viewer"""
  390:         self.title=title
  391:         self.imageViewerUrl=imageViewerUrl
  392:         self.digilibBaseUrl = digilibBaseUrl
  393:         
  394:         if RESPONSE is not None:
  395:             RESPONSE.redirect('manage_main')
  396:     
  397:     
  398:         
  399:         
  400: #    security.declareProtected('View management screens','renameImageForm')
  401: 
  402: def manage_AddDocumentViewerForm(self):
  403:     """add the viewer form"""
  404:     pt=PageTemplateFile('zpt/addDocumentViewer', globals()).__of__(self)
  405:     return pt()
  406:   
  407: def manage_AddDocumentViewer(self,id,imageViewerUrl="",title="",RESPONSE=None):
  408:     """add the viewer"""
  409:     newObj=documentViewer(id,imageViewerUrl,title)
  410:     self._setObject(id,newObj)
  411:     
  412:     if RESPONSE is not None:
  413:         RESPONSE.redirect('manage_main')
  414: 
  415: 
  416: ##
  417: ## DocumentViewerTemplate class
  418: ##
  419: class DocumentViewerTemplate(ZopePageTemplate):
  420:     """Template for document viewer"""
  421:     meta_type="DocumentViewer Template"
  422: 
  423: 
  424: def manage_addDocumentViewerTemplateForm(self):
  425:     """Form for adding"""
  426:     pt=PageTemplateFile('zpt/addDocumentViewerTemplate', globals()).__of__(self)
  427:     return pt()
  428: 
  429: def manage_addDocumentViewerTemplate(self, id='viewer_main', title=None, text=None,
  430:                            REQUEST=None, submit=None):
  431:     "Add a Page Template with optional file content."
  432: 
  433:     self._setObject(id, DocumentViewerTemplate(id))
  434:     ob = getattr(self, id)
  435:     ob.pt_edit(open(os.path.join(package_home(globals()),'zpt/viewer_main.zpt')).read(),None)
  436:     if title:
  437:         ob.pt_setTitle(title)
  438:     try:
  439:         u = self.DestinationURL()
  440:     except AttributeError:
  441:         u = REQUEST['URL1']
  442:         
  443:     u = "%s/%s" % (u, urllib.quote(id))
  444:     REQUEST.RESPONSE.redirect(u+'/manage_main')
  445:     return ''
  446: 
  447: 
  448:     

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