0
|
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
|
22
|
19 import zLOG
|
0
|
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"""
|
22
|
40 imageUrl=genericDigilib+"/dirInfo-xml.jsp?mo=dir&fn="+path
|
0
|
41
|
22
|
42 zLOG.LOG("documentViewer (getparamfromdigilib)", zLOG.INFO, "dirInfo (%s) from %s"%(param,imageUrl))
|
|
43
|
0
|
44 try:
|
|
45 dom = NonvalidatingReader.parseUri(imageUrl)
|
|
46 except:
|
|
47 return None
|
|
48
|
22
|
49 params=dom.xpath("//dir/%s"%param)
|
|
50 zLOG.LOG("documentViewer (getparamfromdigilib)", zLOG.INFO, "dirInfo:%s"%params)
|
0
|
51
|
|
52 if params:
|
22
|
53 return getTextFromNode(params[0])
|
|
54
|
0
|
55
|
|
56
|
|
57
|
22
|
58 ##
|
|
59 ## documentViewer class
|
|
60 ##
|
|
61 class documentViewer(Folder):
|
0
|
62 """document viewer"""
|
|
63
|
|
64 meta_type="Document viewer"
|
|
65
|
|
66 security=ClassSecurityInfo()
|
22
|
67 manage_options=Folder.manage_options+(
|
0
|
68 {'label':'main config','action':'changeDocumentViewerForm'},
|
|
69 )
|
|
70
|
22
|
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
|
0
|
81
|
22
|
82 def __init__(self,id,imageViewerUrl,title="",digilibBaseUrl=None):
|
0
|
83 """init document viewer"""
|
|
84 self.id=id
|
|
85 self.title=title
|
|
86 self.imageViewerUrl=imageViewerUrl
|
22
|
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 '''
|
0
|
101
|
22
|
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)
|
0
|
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
|
22
|
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
|
0
|
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
|
22
|
159 ret+="""<select onChange="location.href='%s&start='+this.options[this.selectedIndex].value">"""%newUrlSelect
|
0
|
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
|
22
|
179
|
0
|
180
|
|
181
|
22
|
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))
|
20
|
185
|
22
|
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
|
20
|
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)
|
22
|
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
|
20
|
277
|
22
|
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
|
20
|
300
|
|
301
|
22
|
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
|
0
|
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
|
20
|
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
|
22
|
361 #
|
|
362
|
0
|
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)
|
20
|
367 if not viewerUrl:
|
|
368 viewerUrl=self.imageViewerUrl
|
0
|
369 url=viewerUrl+"pn=%s&fn=%s"%(pn,imagepath[0])
|
|
370 ret="""<iframe height="100%%" width="100%%" src="%s"/>"""%url
|
|
371 return url
|
20
|
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
|
0
|
378
|
22
|
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
|
0
|
393
|
22
|
394 if RESPONSE is not None:
|
|
395 RESPONSE.redirect('manage_main')
|
0
|
396
|
|
397
|
|
398
|
|
399
|
|
400 # security.declareProtected('View management screens','renameImageForm')
|
|
401
|
|
402 def manage_AddDocumentViewerForm(self):
|
|
403 """add the viewer form"""
|
22
|
404 pt=PageTemplateFile('zpt/addDocumentViewer', globals()).__of__(self)
|
0
|
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')
|
22
|
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
|
0
|
448 |