source: documentViewer/documentViewer.py @ 476:1d93a8cb2d8f

elementtree
Last change on this file since 476:1d93a8cb2d8f was 476:1d93a8cb2d8f, checked in by casties, 13 years ago

more new template stuff

File size: 31.6 KB
Line 
1from OFS.Folder import Folder
2from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
3from Products.PageTemplates.PageTemplateFile import PageTemplateFile
4from AccessControl import ClassSecurityInfo
5from AccessControl import getSecurityManager
6from Globals import package_home
7
8#from Ft.Xml import EMPTY_NAMESPACE, Parse
9#import Ft.Xml.Domlette
10
11import xml.etree.ElementTree as ET
12
13import os.path
14import sys
15import urllib
16import logging
17import math
18import urlparse 
19import re
20import string
21
22from SrvTxtUtils import getInt, getText, getHttpData
23
24def logger(txt,method,txt2):
25    """logging"""
26    logging.info(txt+ txt2)
27   
28   
29def serializeNode(node, encoding="utf-8"):
30    """returns a string containing node as XML"""
31    s = ET.tostring(node)
32   
33    # 4Suite:
34    #    stream = cStringIO.StringIO()
35    #    Ft.Xml.Domlette.Print(node, stream=stream, encoding=encoding)
36    #    s = stream.getvalue()
37    #    stream.close()
38    return s
39
40def browserCheck(self):
41    """check the browsers request to find out the browser type"""
42    bt = {}
43    ua = self.REQUEST.get_header("HTTP_USER_AGENT")
44    bt['ua'] = ua
45    bt['isIE'] = False
46    bt['isN4'] = False
47    bt['versFirefox']=""
48    bt['versIE']=""
49    bt['versSafariChrome']=""
50    bt['versOpera']=""
51   
52    if string.find(ua, 'MSIE') > -1:
53        bt['isIE'] = True
54    else:
55        bt['isN4'] = (string.find(ua, 'Mozilla/4.') > -1)
56    # Safari oder Chrome identification   
57    try:
58        nav = ua[string.find(ua, '('):]
59        nav1=ua[string.find(ua,')'):]
60        nav2=nav1[string.find(nav1,'('):]
61        nav3=nav2[string.find(nav2,')'):]
62        ie = string.split(nav, "; ")[1]
63        ie1 =string.split(nav1, " ")[2]
64        ie2 =string.split(nav3, " ")[1]
65        ie3 =string.split(nav3, " ")[2]
66        if string.find(ie3, "Safari") >-1:
67            bt['versSafariChrome']=string.split(ie2, "/")[1]
68    except: pass
69    # IE identification
70    try:
71        nav = ua[string.find(ua, '('):]
72        ie = string.split(nav, "; ")[1]
73        if string.find(ie, "MSIE") > -1:
74            bt['versIE'] = string.split(ie, " ")[1]
75    except:pass
76    # Firefox identification
77    try:
78        nav = ua[string.find(ua, '('):]
79        nav1=ua[string.find(ua,')'):]
80        if string.find(ie1, "Firefox") >-1:
81            nav5= string.split(ie1, "/")[1]
82            logging.debug("FIREFOX: %s"%(nav5))
83            bt['versFirefox']=nav5[0:3]                   
84    except:pass
85    #Opera identification
86    try:
87        if string.find(ua,"Opera") >-1:
88            nav = ua[string.find(ua, '('):]
89            nav1=nav[string.find(nav,')'):]
90            bt['versOpera']=string.split(nav1,"/")[2]
91    except:pass
92   
93    bt['isMac'] = string.find(ua, 'Macintosh') > -1
94    bt['isWin'] = string.find(ua, 'Windows') > -1
95    bt['isIEWin'] = bt['isIE'] and bt['isWin']
96    bt['isIEMac'] = bt['isIE'] and bt['isMac']
97    bt['staticHTML'] = False
98
99    return bt
100
101def getParentPath(path, cnt=1):
102    """returns pathname shortened by cnt"""
103    # make sure path doesn't end with /
104    path = path.rstrip('/')
105    # split by /, shorten, and reassemble
106    return '/'.join(path.split('/')[0:-cnt])
107
108
109##
110## documentViewer class
111##
112class documentViewer(Folder):
113    """document viewer"""
114    meta_type="Document viewer"
115   
116    security=ClassSecurityInfo()
117    manage_options=Folder.manage_options+(
118        {'label':'main config','action':'changeDocumentViewerForm'},
119        )
120   
121    metadataService = None
122    """MetaDataFolder instance"""
123
124    # templates and forms
125    viewer_main = PageTemplateFile('zpt/viewer_main', globals())
126    toc_thumbs = PageTemplateFile('zpt/toc_thumbs', globals())
127    toc_text = PageTemplateFile('zpt/toc_text', globals())
128    toc_figures = PageTemplateFile('zpt/toc_figures', globals())
129    page_main_images = PageTemplateFile('zpt/page_main_images', globals())
130    page_main_double = PageTemplateFile('zpt/page_main_double', globals())
131    page_main_text = PageTemplateFile('zpt/page_main_text', globals())
132    page_main_text_dict = PageTemplateFile('zpt/page_main_text_dict', globals())
133    page_main_gis =PageTemplateFile ('zpt/page_main_gis', globals())
134    page_main_xml = PageTemplateFile('zpt/page_main_xml', globals())
135    page_main_pureXml = PageTemplateFile('zpt/page_main_pureXml', globals())
136    head_main = PageTemplateFile('zpt/head_main', globals())
137    docuviewer_css = PageTemplateFile('css/docuviewer.css', globals())
138    info_xml = PageTemplateFile('zpt/info_xml', globals())
139   
140   
141    thumbs_main_rss = PageTemplateFile('zpt/thumbs_main_rss', globals())
142
143   
144    def __init__(self,id,imageScalerUrl=None,textServerName=None,title="",digilibBaseUrl=None,thumbcols=2,thumbrows=5,authgroups="mpiwg"):
145        """init document viewer"""
146        self.id=id
147        self.title=title
148        self.thumbcols = thumbcols
149        self.thumbrows = thumbrows
150        # authgroups is list of authorized groups (delimited by ,)
151        self.authgroups = [s.strip().lower() for s in authgroups.split(',')]
152        # create template folder so we can always use template.something
153       
154        templateFolder = Folder('template')
155        #self['template'] = templateFolder # Zope-2.12 style
156        self._setObject('template',templateFolder) # old style
157        try:
158            import MpdlXmlTextServer
159            textServer = MpdlXmlTextServer.MpdlXmlTextServer(id='fulltextclient',serverName=textServerName)
160            #templateFolder['fulltextclient'] = xmlRpcClient
161            templateFolder._setObject('fulltextclient',textServer)
162        except Exception, e:
163            logging.error("Unable to create MpdlXmlTextServer for fulltextclient: "+str(e))
164           
165        try:
166            from Products.zogiLib.zogiLib import zogiLib
167            zogilib = zogiLib(id="zogilib", title="zogilib for docuviewer", dlServerURL=imageScalerUrl, layout="book")
168            #templateFolder['zogilib'] = zogilib
169            templateFolder._setObject('zogilib',zogilib)
170        except Exception, e:
171            logging.error("Unable to create zogiLib for zogilib: "+str(e))
172           
173        try:
174            # assume MetaDataFolder instance is called metadata
175            self.metadataService = getattr(self, 'metadata')
176        except Exception, e:
177            logging.error("Unable to find MetaDataFolder 'metadata': "+str(e))
178           
179       
180    # proxy text server methods to fulltextclient
181    def getTextPage(self, **args):
182        """get page"""
183        return self.template.fulltextclient.getTextPage(**args)
184
185    def getOrigPages(self, **args):
186        """get page"""
187        return self.template.fulltextclient.getOrigPages(**args)
188   
189    def getOrigPagesNorm(self, **args):
190        """get page"""
191        return self.template.fulltextclient.getOrigPagesNorm(**args)
192
193    def getQuery(self, **args):
194        """get query in search"""
195        return self.template.fulltextclient.getQuery(**args)
196     
197    def getSearch(self, **args):
198        """get search"""
199        return self.template.fulltextclient.getSearch(**args)
200   
201    def getGisPlaces(self, **args):
202        """get gis places"""
203        return self.template.fulltextclient.getGisPlaces(**args)
204 
205    def getAllGisPlaces(self, **args):
206        """get all gis places """
207        return self.template.fulltextclient.getAllGisPlaces(**args)
208       
209    def getTranslate(self, **args):
210        """get translate"""
211        return self.template.fulltextclient.getTranslate(**args)
212
213    def getLemma(self, **args):
214        """get lemma"""
215        return self.template.fulltextclient.getLemma(**args)
216
217    def getLemmaQuery(self, **args):
218        """get query"""
219        return self.template.fulltextclient.getLemmaQuery(**args)
220
221    def getLex(self, **args):
222        """get lex"""
223        return self.template.fulltextclient.getLex(**args)
224
225    def getToc(self, **args):
226        """get toc"""
227        return self.template.fulltextclient.getToc(**args)
228
229    def getTocPage(self, **args):
230        """get tocpage"""
231        return self.template.fulltextclient.getTocPage(**args)
232
233   
234    security.declareProtected('View','thumbs_rss')
235    def thumbs_rss(self,mode,url,viewMode="auto",start=None,pn=1):
236        '''
237        view it
238        @param mode: defines how to access the document behind url
239        @param url: url which contains display information
240        @param viewMode: if images display images, if text display text, default is images (text,images or auto)
241       
242        '''
243        logging.debug("HHHHHHHHHHHHHH:load the rss")
244        logging.debug("documentViewer (index) mode: %s url:%s start:%s pn:%s"%(mode,url,start,pn))
245       
246        if not hasattr(self, 'template'):
247            # create template folder if it doesn't exist
248            self.manage_addFolder('template')
249           
250        if not self.digilibBaseUrl:
251            self.digilibBaseUrl = self.findDigilibUrl() or "http://nausikaa.mpiwg-berlin.mpg.de/digitallibrary"
252           
253        docinfo = self.getDocinfo(mode=mode,url=url)
254        #pageinfo = self.getPageinfo(start=start,current=pn,docinfo=docinfo)
255        pageinfo = self.getPageinfo(start=start,current=pn, docinfo=docinfo)
256        ''' ZDES '''
257        pt = getattr(self.template, 'thumbs_main_rss')
258       
259        if viewMode=="auto": # automodus gewaehlt
260            if docinfo.has_key("textURL") or docinfo.get('textURLPath',None): #texturl gesetzt und textViewer konfiguriert
261                viewMode="text"
262            else:
263                viewMode="images"
264               
265        return pt(docinfo=docinfo,pageinfo=pageinfo,viewMode=viewMode)
266
267 
268    security.declareProtected('View','index_html')
269    def index_html(self,url,mode="texttool",viewMode="auto",viewType=None,tocMode="thumbs",start=1,pn=1):
270        """
271        view page
272        @param url: url which contains display information
273        @param mode: defines how to access the document behind url
274        @param viewMode: 'images': display images, 'text': display text, default is 'auto'
275        @param viewType: sub-type of viewMode, e.g. 'dict' for viewMode='text'
276        @param tocMode: type of 'table of contents' for navigation (thumbs, text, figures, none)
277        """
278       
279        logging.debug("documentViewer(index_html) mode=%s url=%s viewMode=%s viewType=%s start=%s pn=%s"%(mode,url,viewMode,viewType,start,pn))
280       
281        if not hasattr(self, 'template'):
282            # this won't work
283            logging.error("template folder missing!")
284            return "ERROR: template folder missing!"
285           
286        if not getattr(self, 'digilibBaseUrl', None):
287            self.digilibBaseUrl = self.findDigilibUrl() or "http://digilib.mpiwg-berlin.mpg.de/digitallibrary"
288           
289        docinfo = self.getDocinfo(mode=mode,url=url)
290       
291        if tocMode != "thumbs":
292            # get table of contents
293            docinfo = self.getToc(mode=tocMode, docinfo=docinfo)
294
295        # auto viewMode: text if there is a text else images
296        if viewMode=="auto": 
297            if docinfo.get('textURL', None) or docinfo.get('textURLPath', None): 
298                viewMode = "text"
299                viewType = "dict"
300            else:
301                viewMode = "images"
302               
303        elif viewMode == "text_dict":
304            # legacy fix
305            viewMode = "text"
306            viewType = "dict"
307           
308        # stringify viewType
309        if isinstance(viewType, list):
310            viewType = ','.join([t for t in viewType if t])
311                       
312        pageinfo = self.getPageinfo(start=start, current=pn, docinfo=docinfo, viewMode=viewMode, viewType=viewType, tocMode=tocMode)
313                   
314        # get template /template/viewer_$viewMode
315        pt = getattr(self.template, 'viewer_%s'%viewMode, None)
316        if pt is None:
317            logging.error("No template for viewMode=%s!"%viewMode)
318            # TODO: error page?
319            return "No template for viewMode=%s!"%viewMode
320       
321        # and execute with parameters
322        return pt(docinfo=docinfo, pageinfo=pageinfo)
323 
324    def generateMarks(self,mk):
325        ret=""
326        if mk is None:
327            return ""
328        if not isinstance(mk, list):
329            mk=[mk]
330        for m in mk:
331            ret+="mk=%s"%m
332        return ret
333   
334   
335    def getBrowser(self):
336        """getBrowser the version of browser """
337        bt = browserCheck(self)
338        logging.debug("BROWSER VERSION: %s"%(bt))
339        return bt
340       
341    def findDigilibUrl(self):
342        """try to get the digilib URL from zogilib"""
343        url = self.template.zogilib.getDLBaseUrl()
344        return url
345
346    def getDocumentViewerURL(self):
347        """returns the URL of this instance"""
348        return self.absolute_url()
349   
350    def getStyle(self, idx, selected, style=""):
351        """returns a string with the given style and append 'sel' if path == selected."""
352        #logger("documentViewer (getstyle)", logging.INFO, "idx: %s selected: %s style: %s"%(idx,selected,style))
353        if idx == selected:
354            return style + 'sel'
355        else:
356            return style
357   
358    def getParams(self, param=None, val=None, params=None):
359        """returns dict with URL parameters.
360       
361        Takes URL parameters and additionally param=val or dict params.
362        Deletes key if value is None."""
363        # copy existing request params
364        newParams=self.REQUEST.form.copy()
365        # change single param
366        if param is not None:
367            if val is None:
368                if newParams.has_key(param):
369                    del newParams[param]
370            else:
371                newParams[param] = str(val)
372               
373        # change more params
374        if params is not None:
375            for k in params.keys():
376                v = params[k]
377                if v is None:
378                    # val=None removes param
379                    if newParams.has_key(k):
380                        del newParams[k]
381                       
382                else:
383                    newParams[k] = v
384                   
385        return newParams
386   
387    def getLink(self, param=None, val=None, params=None, baseUrl=None, paramSep='&'):
388        """returns URL to documentviewer with parameter param set to val or from dict params"""
389        urlParams = self.getParams(param=param, val=val, params=params)
390        # quote values and assemble into query string (not escaping '/')
391        ps = paramSep.join(["%s=%s"%(k,urllib.quote_plus(unicode(v),'/')) for (k, v) in urlParams.items()])
392        if baseUrl is None:
393            baseUrl = self.getDocumentViewerURL()
394           
395        url = "%s?%s"%(baseUrl, ps)
396        return url
397
398    def getLinkAmp(self, param=None, val=None, params=None, baseUrl=None):
399        """link to documentviewer with parameter param set to val"""
400        return self.getLink(param, val, params, baseUrl, '&')
401   
402   
403    def getInfo_xml(self,url,mode):
404        """returns info about the document as XML"""
405        if not self.digilibBaseUrl:
406            self.digilibBaseUrl = self.findDigilibUrl() or "http://nausikaa.mpiwg-berlin.mpg.de/digitallibrary"
407       
408        docinfo = self.getDocinfo(mode=mode,url=url)
409        pt = getattr(self.template, 'info_xml')
410        return pt(docinfo=docinfo)
411
412    def isAccessible(self, docinfo):
413        """returns if access to the resource is granted"""
414        access = docinfo.get('accessType', None)
415        logging.debug("documentViewer (accessOK) access type %s"%access)
416        if access == 'free':
417            logging.debug("documentViewer (accessOK) access is free")
418            return True
419       
420        elif access is None or access in self.authgroups:
421            # only local access -- only logged in users
422            user = getSecurityManager().getUser()
423            logging.debug("documentViewer (accessOK) user=%s ip=%s"%(user,self.REQUEST.getClientAddr()))
424            if user is not None:
425                #print "user: ", user
426                return (user.getUserName() != "Anonymous User")
427            else:
428                return False
429       
430        logging.error("documentViewer (accessOK) unknown access type %s"%access)
431        return False
432   
433
434
435    def getDocinfo(self, mode, url):
436        """returns docinfo depending on mode"""
437        logging.debug("getDocinfo: mode=%s, url=%s"%(mode,url))
438        # look for cached docinfo in session
439        if self.REQUEST.SESSION.has_key('docinfo'):
440            docinfo = self.REQUEST.SESSION['docinfo']
441            # check if its still current
442            if docinfo is not None and docinfo.get('mode', None) == mode and docinfo.get('url', None) == url:
443                logging.debug("getDocinfo: docinfo in session. keys=%s"%docinfo.keys())
444                return docinfo
445           
446        # new docinfo
447        docinfo = {'mode': mode, 'url': url}
448        # add self url
449        docinfo['viewerUrl'] = self.getDocumentViewerURL()
450        # get index.meta DOM
451        docUrl = None
452        metaDom = None
453        if mode=="texttool": 
454            # url points to document dir or index.meta
455            metaDom = self.metadataService.getDomFromPathOrUrl(url)
456            docUrl = url.replace('/index.meta', '')
457            if metaDom is None:
458                raise IOError("Unable to find index.meta for mode=texttool!")
459
460        elif mode=="imagepath":
461            # url points to folder with images, index.meta optional
462            # asssume index.meta in parent dir
463            docUrl = getParentPath(url)
464            metaDom = self.metadataService.getDomFromPathOrUrl(docUrl)
465
466        elif mode=="filepath":
467            # url points to image file, index.meta optional
468            # asssume index.meta is two path segments up
469            docUrl = getParentPath(url, 2)
470            metaDom = self.metadataService.getDomFromPathOrUrl(docUrl)
471
472        else:
473            logging.error("documentViewer (getdocinfo) unknown mode: %s!"%mode)
474            raise ValueError("Unknown mode %s! Has to be one of 'texttool','imagepath','filepath'."%(mode))
475       
476        docinfo['documentUrl'] = docUrl
477        # process index.meta contents
478        if metaDom is not None and metaDom.tag == 'resource':
479            # document directory name and path
480            resource = self.metadataService.getResourceData(dom=metaDom)
481            if resource:
482                docinfo = self.getDocinfoFromResource(docinfo, resource)
483
484            # texttool info
485            texttool = self.metadataService.getTexttoolData(dom=metaDom)
486            if texttool:
487                docinfo = self.getDocinfoFromTexttool(docinfo, texttool)
488           
489            # bib info
490            bib = self.metadataService.getBibData(dom=metaDom)
491            if bib:
492                docinfo = self.getDocinfoFromBib(docinfo, bib)
493            else:
494                # no bib - try info.xml
495                docinfo = self.getDocinfoFromPresentationInfoXml(docinfo)
496               
497            # auth info
498            access = self.metadataService.getAccessData(dom=metaDom)
499            if access:
500                docinfo = self.getDocinfoFromAccess(docinfo, access)
501
502            # attribution info
503            attribution = self.metadataService.getAttributionData(dom=metaDom)
504            if attribution:
505                logging.debug("getDocinfo: attribution=%s"%repr(attribution))
506                docinfo['attribution'] = attribution
507                #docinfo = self.getDocinfoFromAccess(docinfo, access)
508
509            # copyright info
510            copyright = self.metadataService.getCopyrightData(dom=metaDom)
511            if copyright:
512                logging.debug("getDocinfo: copyright=%s"%repr(copyright))
513                docinfo['copyright'] = copyright
514                #docinfo = self.getDocinfoFromAccess(docinfo, access)
515
516        # image path
517        if mode != 'texttool':
518            # override image path from texttool
519            docinfo['imagePath'] = url.replace('/mpiwg/online/', '', 1)
520
521        # number of images from digilib
522        if docinfo.get('imagePath', None):
523            docinfo['imageURL'] = self.digilibBaseUrl + "/servlet/Scaler?fn=" + docinfo['imagePath']
524            docinfo = self.getDocinfoFromDigilib(docinfo, docinfo['imagePath'])
525
526        logging.debug("documentViewer (getdocinfo) docinfo: keys=%s"%docinfo.keys())
527        #logging.debug("documentViewer (getdocinfo) docinfo: %s"%docinfo)
528        # store in session
529        self.REQUEST.SESSION['docinfo'] = docinfo
530        return docinfo
531
532    def getDocinfoFromResource(self, docinfo, resource):
533        """reads contents of resource element into docinfo"""
534        docName = resource.get('name', None)
535        docinfo['documentName'] = docName
536        docPath = resource.get('archive-path', None)
537        if docPath:
538            # clean up document path
539            if docPath[0] != '/':
540                docPath = '/' + docPath
541               
542            if docName and (not docPath.endswith(docName)):
543                docPath += "/" + docName
544           
545        else:
546            # use docUrl as docPath
547            docUrl = docinfo['documentURL']
548            if not docUrl.startswith('http:'):
549                docPath = docUrl
550        if docPath:
551            # fix URLs starting with /mpiwg/online
552            docPath = docPath.replace('/mpiwg/online', '', 1)
553
554        docinfo['documentPath'] = docPath
555        return docinfo
556
557    def getDocinfoFromTexttool(self, docinfo, texttool):
558        """reads contents of texttool element into docinfo"""
559        # image dir
560        imageDir = texttool.get('image', None)
561        docPath = docinfo.get('documentPath', None)
562        if imageDir and docPath:
563            #print "image: ", imageDir, " archivepath: ", archivePath
564            imageDir = os.path.join(docPath, imageDir)
565            imageDir = imageDir.replace('/mpiwg/online', '', 1)
566            docinfo['imagePath'] = imageDir
567       
568        # old style text URL
569        textUrl = texttool.get('text', None)
570        if textUrl and docPath:
571            if urlparse.urlparse(textUrl)[0] == "": #keine url
572                textUrl = os.path.join(docPath, textUrl) 
573           
574            docinfo['textURL'] = textUrl
575   
576        # new style text-url-path
577        textUrl = texttool.get('text-url-path', None)
578        if textUrl:
579            docinfo['textURLPath'] = textUrl
580           
581        # page flow
582        docinfo['pageFlow'] = texttool.get('page-flow', 'ltr')
583           
584        # odd pages are left
585        docinfo['oddPage'] = texttool.get('odd-scan-position', 'left')
586           
587        # number of title page (0: not defined)
588        docinfo['titlePage'] = texttool.get('title-scan-no', 0)
589           
590        # old presentation stuff
591        presentation = texttool.get('presentation', None)
592        if presentation and docPath:
593            if presentation.startswith('http:'):
594                docinfo['presentationUrl'] = presentation
595            else:
596                docinfo['presentationUrl'] = os.path.join(docPath, presentation)
597           
598       
599        return docinfo
600
601    def getDocinfoFromBib(self, docinfo, bib):
602        """reads contents of bib element into docinfo"""
603        logging.debug("getDocinfoFromBib bib=%s"%repr(bib))
604        # put all raw bib fields in dict "bib"
605        docinfo['bib'] = bib
606        bibtype = bib.get('@type', None)
607        docinfo['bibType'] = bibtype
608        # also store DC metadata for convenience
609        dc = self.metadataService.getDCMappedData(bib)
610        docinfo['creator'] = dc.get('creator',None)
611        docinfo['title'] = dc.get('title',None)
612        docinfo['date'] = dc.get('date',None)
613        return docinfo
614           
615    def getDocinfoFromAccess(self, docinfo, acc):
616        """reads contents of access element into docinfo"""
617        #TODO: also read resource type
618        logging.debug("getDocinfoFromAccess acc=%s"%repr(acc))
619        try:
620            acctype = acc['@attr']['type']
621            if acctype:
622                access=acctype
623                if access in ['group', 'institution']:
624                    access = acc['name'].lower()
625               
626                docinfo['accessType'] = access
627
628        except:
629            pass
630       
631        return docinfo
632
633    def getDocinfoFromDigilib(self, docinfo, path):
634        infoUrl=self.digilibBaseUrl+"/dirInfo-xml.jsp?mo=dir&fn="+path
635        # fetch data
636        txt = getHttpData(infoUrl)
637        if not txt:
638            logging.error("Unable to get dir-info from %s"%(infoUrl))
639            return docinfo
640
641        dom = ET.fromstring(txt)
642        size = getText(dom.find("size"))
643        logging.debug("getDocinfoFromDigilib: size=%s"%size)
644        if size:
645            docinfo['numPages'] = int(size)
646        else:
647            docinfo['numPages'] = 0
648           
649        # TODO: produce and keep list of image names and numbers
650        return docinfo
651           
652           
653    def getDocinfoFromPresentationInfoXml(self,docinfo):
654        """gets DC-like bibliographical information from the presentation entry in texttools"""
655        url = docinfo.get('presentationUrl', None)
656        if not url:
657            logging.error("getDocinfoFromPresentation: no URL!")
658            return docinfo
659       
660        dom = None
661        metaUrl = None
662        if url.startswith("http://"):
663            # real URL
664            metaUrl = url
665        else:
666            # online path
667           
668            server=self.digilibBaseUrl+"/servlet/Texter?fn="
669            metaUrl=server+url
670       
671        txt=getHttpData(metaUrl)
672        if txt is None:
673            logging.error("Unable to read info.xml from %s"%(url))
674            return docinfo
675           
676        dom = ET.fromstring(txt)
677        docinfo['creator']=getText(dom.find(".//author"))
678        docinfo['title']=getText(dom.find(".//title"))
679        docinfo['date']=getText(dom.find(".//date"))
680        return docinfo
681   
682
683    def getPageinfo(self, current, start=None, rows=None, cols=None, docinfo=None, viewMode=None, viewType=None, tocMode=None):
684        """returns pageinfo with the given parameters"""
685        pageinfo = {}
686        pageinfo['viewMode'] = viewMode
687        pageinfo['viewType'] = viewType
688        pageinfo['tocMode'] = tocMode
689
690        current = getInt(current)
691        pageinfo['current'] = current
692        rows = int(rows or self.thumbrows)
693        pageinfo['rows'] = rows
694        cols = int(cols or self.thumbcols)
695        pageinfo['cols'] = cols
696        grpsize = cols * rows
697        pageinfo['groupsize'] = grpsize
698        # is start is empty use one around current
699        start = getInt(start, default=(math.ceil(float(current)/float(grpsize))*grpsize-(grpsize-1)))
700        # int(current / grpsize) * grpsize +1))
701        pageinfo['start'] = start
702        pn = self.REQUEST.get('pn','1')
703        pageinfo['pn'] = pn
704        np = int(docinfo.get('numPages', 0))
705        if np == 0:
706            # numPages unknown - maybe we can get it from text page
707            if docinfo.get('textURLPath', None):
708                # cache text page as well
709                pageinfo['textPage'] = self.getTextPage(mode=viewType, pn=pn, docinfo=docinfo, pageinfo=pageinfo)
710                np = int(docinfo.get('numPages', 0))
711               
712        pageinfo['numgroups'] = int(np / grpsize)
713        if np % grpsize > 0:
714            pageinfo['numgroups'] += 1
715
716        pageFlowLtr = docinfo.get('pageFlow', 'ltr') != 'rtl'
717        oddScanLeft = docinfo.get('oddPage', 'left') != 'right'
718        # add zeroth page for two columns
719        pageZero = (cols == 2 and (pageFlowLtr != oddScanLeft))
720        pageinfo['pageZero'] = pageZero
721        pageinfo['pageList'] = self.getPageList(start=start, rows=rows, cols=cols, pageFlowLtr=pageFlowLtr, pageZero=pageZero, minIdx=1, maxIdx=np)
722               
723        pageinfo['characterNormalization'] = self.REQUEST.get('characterNormalization','reg')
724        pageinfo['query'] = self.REQUEST.get('query','') 
725        pageinfo['queryType'] = self.REQUEST.get('queryType','')
726        pageinfo['querySearch'] =self.REQUEST.get('querySearch', 'fulltext')
727        pageinfo['highlightQuery'] = self.REQUEST.get('highlightQuery','')
728        pageinfo['tocPageSize'] = getInt(self.REQUEST.get('tocPageSize', 30))
729        pageinfo['queryPageSize'] = getInt(self.REQUEST.get('queryPageSize', 10))
730        pageinfo['tocPN'] = getInt(self.REQUEST.get('tocPN', '1'))
731        pageinfo['searchPN'] = getInt(self.REQUEST.get('searchPN','1'))
732       
733        # limit tocPN
734        if 'tocSize_%s'%tocMode in docinfo:
735            tocSize = docinfo['tocSize_%s'%tocMode]
736            tocPageSize = pageinfo['tocPageSize']
737            # cached toc           
738            if tocSize%tocPageSize>0:
739                tocPages=tocSize/tocPageSize+1
740            else:
741                tocPages=tocSize/tocPageSize
742               
743            pageinfo['tocPN'] = min(tocPages,pageinfo['tocPN'])
744           
745        return pageinfo
746
747
748    def getPageList(self, start=None, rows=None, cols=None, pageFlowLtr=True, pageZero=False, minIdx=1, maxIdx=0):
749        """returns array of page informations for one screenfull of thumbnails"""
750        if maxIdx == 0:
751            maxIdx = start + rows * cols
752
753        pages = []
754        if pageZero and start == 1:
755            # correct beginning
756            idx = 0
757        else:
758            idx = start
759           
760        for r in range(rows):
761            row = []
762            for c in range(cols):
763                if idx < minIdx or idx > maxIdx:
764                    page = {'idx':None}
765                else:
766                    page = {'idx':idx}
767                   
768                idx += 1
769                if pageFlowLtr:
770                    row.append(page)
771                else:
772                    row.insert(0, page) 
773               
774            pages.append(row)
775           
776        logging.debug("getPageList returns=%s"%(pages))
777        return pages
778       
779
780    security.declareProtected('View management screens','changeDocumentViewerForm')   
781    changeDocumentViewerForm = PageTemplateFile('zpt/changeDocumentViewer', globals())
782   
783    def changeDocumentViewer(self,title="",digilibBaseUrl=None,thumbrows=2,thumbcols=5,authgroups='mpiwg',RESPONSE=None):
784        """init document viewer"""
785        self.title=title
786        self.digilibBaseUrl = digilibBaseUrl
787        self.thumbrows = thumbrows
788        self.thumbcols = thumbcols
789        self.authgroups = [s.strip().lower() for s in authgroups.split(',')]
790        try:
791            # assume MetaDataFolder instance is called metadata
792            self.metadataService = getattr(self, 'metadata')
793        except Exception, e:
794            logging.error("Unable to find MetaDataFolder 'metadata': "+str(e))
795
796        if RESPONSE is not None:
797            RESPONSE.redirect('manage_main')
798       
799def manage_AddDocumentViewerForm(self):
800    """add the viewer form"""
801    pt=PageTemplateFile('zpt/addDocumentViewer', globals()).__of__(self)
802    return pt()
803 
804def manage_AddDocumentViewer(self,id,imageScalerUrl="",textServerName="",title="",RESPONSE=None):
805    """add the viewer"""
806    newObj=documentViewer(id,imageScalerUrl=imageScalerUrl,title=title,textServerName=textServerName)
807    self._setObject(id,newObj)
808   
809    if RESPONSE is not None:
810        RESPONSE.redirect('manage_main')
811
812## DocumentViewerTemplate class
813class DocumentViewerTemplate(ZopePageTemplate):
814    """Template for document viewer"""
815    meta_type="DocumentViewer Template"
816
817
818def manage_addDocumentViewerTemplateForm(self):
819    """Form for adding"""
820    pt=PageTemplateFile('zpt/addDocumentViewerTemplate', globals()).__of__(self)
821    return pt()
822
823def manage_addDocumentViewerTemplate(self, id='viewer_main', title=None, text=None,
824                           REQUEST=None, submit=None):
825    "Add a Page Template with optional file content."
826
827    self._setObject(id, DocumentViewerTemplate(id))
828    ob = getattr(self, id)
829    txt=file(os.path.join(package_home(globals()),'zpt/viewer_main.zpt'),'r').read()
830    logging.info("txt %s:"%txt)
831    ob.pt_edit(txt,"text/html")
832    if title:
833        ob.pt_setTitle(title)
834    try:
835        u = self.DestinationURL()
836    except AttributeError:
837        u = REQUEST['URL1']
838       
839    u = "%s/%s" % (u, urllib.quote(id))
840    REQUEST.RESPONSE.redirect(u+'/manage_main')
841    return ''
842
843
844   
Note: See TracBrowser for help on using the repository browser.