source: documentViewer/documentViewer.py @ 22:b139f9937e97

Last change on this file since 22:b139f9937e97 was 22:b139f9937e97, checked in by casties, 18 years ago

preliminary version 0.2

  • lots of stuff rewritten
  • new template system
  • still no access control
File size: 14.6 KB
Line 
1
2genericDigilib="http://nausikaa2.rz-berlin.mpg.de/digitallibrary/"
3
4from OFS.Folder import Folder
5from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
6from Products.PageTemplates.PageTemplateFile import PageTemplateFile
7from AccessControl import ClassSecurityInfo
8from Globals import package_home
9
10from Ft.Xml.Domlette import NonvalidatingReader
11from Ft.Xml.Domlette import PrettyPrint, Print
12from Ft.Xml import EMPTY_NAMESPACE
13
14import Ft.Xml.XPath
15
16import os.path
17import cgi
18import urllib
19import zLOG
20
21def 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
29import socket
30
31def urlopen(url):
32        """urlopen mit timeout"""
33        socket.setdefaulttimeout(2)
34        ret=urllib.urlopen(url)
35        socket.setdefaulttimeout(5)
36        return ret
37   
38def 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##
61class 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
402def manage_AddDocumentViewerForm(self):
403    """add the viewer form"""
404    pt=PageTemplateFile('zpt/addDocumentViewer', globals()).__of__(self)
405    return pt()
406 
407def 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##
419class DocumentViewerTemplate(ZopePageTemplate):
420    """Template for document viewer"""
421    meta_type="DocumentViewer Template"
422
423
424def manage_addDocumentViewerTemplateForm(self):
425    """Form for adding"""
426    pt=PageTemplateFile('zpt/addDocumentViewerTemplate', globals()).__of__(self)
427    return pt()
428
429def 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   
Note: See TracBrowser for help on using the repository browser.