1:
2: from Products.PageTemplates.PageTemplateFile import PageTemplateFile
3: from Products.PageTemplates.PageTemplate import PageTemplate
4: from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
5: from OFS.Image import Image
6: from webdav.common import rfc1123_date
7:
8: import xml.dom.minidom
9: from OFS.Folder import Folder
10: from xml_helpers import getText
11: import os
12: import re
13: import string
14: import urllib
15: import types
16: from Globals import package_home
17:
18: ZOGIVERSION = "0.9.5 ROC:25.6.2004"
19:
20: def cropf(f):
21: """returns a float with reduced precision"""
22: return float(int(f * 10000)/10000.0)
23:
24:
25: def sendFile(self, filename, type):
26: """sends an object or a local file (in the product) as response"""
27: paths = filename.split('/')
28: object = self
29: # look for an object called filename
30: for path in paths:
31: if hasattr(object, path):
32: object = getattr(object, path)
33: else:
34: object = None
35: break
36: if object:
37: # if the object exists then send it
38: return object.index_html(self.REQUEST.REQUEST, self.REQUEST.RESPONSE)
39: else:
40: # send a local file with the given content-type
41: fn = os.path.join(package_home(globals()), filename)
42: self.REQUEST.RESPONSE.setHeader("Content-Type", type)
43: self.REQUEST.RESPONSE.write(file(fn).read())
44: return
45:
46: def browserCheck(self):
47: """check the browsers request to find out the browser type"""
48: bt = {}
49: ua = self.REQUEST.get_header("HTTP_USER_AGENT")
50: bt['ua'] = ua
51: bt['isIE'] = string.find(ua, 'MSIE') > -1
52: bt['isN4'] = (string.find(ua, 'Mozilla/4.') > -1) and not bt['isIE']
53: nav = ua[string.find(ua, '('):]
54: ie = string.split(nav, "; ")[1]
55: if string.find(ie, "MSIE") > -1:
56: bt['versIE'] = string.split(ie, " ")[1]
57: bt['isMac'] = string.find(ua, 'Macintosh') > -1
58: bt['isWin'] = string.find(ua, 'Windows') > -1
59: bt['isIEWin'] = bt['isIE'] and bt['isWin']
60: bt['isIEMac'] = bt['isIE'] and bt['isMac']
61: bt['staticHTML'] = False
62:
63: return bt
64:
65:
66: class zogiImage(Image):
67: """einzelnes Image"""
68: meta_type="zogiImage"
69:
70: manage_options=ZopePageTemplate.manage_options+(
71: {'label':'Main config','action':'changeZogiImageForm'},
72: )
73:
74:
75: def __init__(self,id,title,baseUrl,queryString,content_type='',precondition=''):
76: """init"""
77: self.id=id
78: self.title=title
79: self.baseUrl=baseUrl
80: self.queryString=queryString
81: self.content_type=content_type
82: self.precondition=precondition
83:
84: def getData(self):
85: """getUrlData"""
86: return urllib.urlopen(self.baseUrl+self.queryString)
87:
88: def changeZogiImageForm(self):
89: """Main configuration"""
90: pt=PageTemplateFile(os.path.join(package_home(globals()), 'zpt/changeZogiImageForm.zpt')).__of__(self)
91: return pt()
92:
93: def changeZogiImage(self,title,baseUrl, queryString,RESPONSE=None):
94: """change it"""
95: self.title=title
96: self.baseUrl=baseUrl
97: self.queryString=queryString
98:
99: if RESPONSE is not None:
100: RESPONSE.redirect('manage_main')
101:
102:
103: def index_html(self, REQUEST, RESPONSE):
104: """
105: Modified version of OFS/Image.py
106:
107: The default view of the contents of a File or Image.
108:
109: Returns the contents of the file or image. Also, sets the
110: Content-Type HTTP header to the objects content type.
111: """
112:
113: # HTTP If-Modified-Since header handling.
114: header=REQUEST.get_header('If-Modified-Since', None)
115: if header is not None:
116: header=header.split( ';')[0]
117: # Some proxies seem to send invalid date strings for this
118: # header. If the date string is not valid, we ignore it
119: # rather than raise an error to be generally consistent
120: # with common servers such as Apache (which can usually
121: # understand the screwy date string as a lucky side effect
122: # of the way they parse it).
123: # This happens to be what RFC2616 tells us to do in the face of an
124: # invalid date.
125: try: mod_since=long(DateTime(header).timeTime())
126: except: mod_since=None
127: if mod_since is not None:
128: if self._p_mtime:
129: last_mod = long(self._p_mtime)
130: else:
131: last_mod = long(0)
132: if last_mod > 0 and last_mod <= mod_since:
133: # Set header values since apache caching will return Content-Length
134: # of 0 in response if size is not set here
135: RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime))
136: RESPONSE.setHeader('Content-Type', self.content_type)
137: RESPONSE.setHeader('Content-Length', self.size)
138: RESPONSE.setHeader('Accept-Ranges', 'bytes')
139: self.ZCacheable_set(None)
140: RESPONSE.setStatus(304)
141: return ''
142:
143: if self.precondition and hasattr(self,self.precondition):
144: # Grab whatever precondition was defined and then
145: # execute it. The precondition will raise an exception
146: # if something violates its terms.
147: c=getattr(self,self.precondition)
148: if hasattr(c,'isDocTemp') and c.isDocTemp:
149: c(REQUEST['PARENTS'][1],REQUEST)
150: else:
151: c()
152:
153: # HTTP Range header handling
154: range = REQUEST.get_header('Range', None)
155: request_range = REQUEST.get_header('Request-Range', None)
156: if request_range is not None:
157: # Netscape 2 through 4 and MSIE 3 implement a draft version
158: # Later on, we need to serve a different mime-type as well.
159: range = request_range
160: if_range = REQUEST.get_header('If-Range', None)
161: if range is not None:
162: ranges = HTTPRangeSupport.parseRange(range)
163:
164: if if_range is not None:
165: # Only send ranges if the data isn't modified, otherwise send
166: # the whole object. Support both ETags and Last-Modified dates!
167: if len(if_range) > 1 and if_range[:2] == 'ts':
168: # ETag:
169: if if_range != self.http__etag():
170: # Modified, so send a normal response. We delete
171: # the ranges, which causes us to skip to the 200
172: # response.
173: ranges = None
174: else:
175: # Date
176: date = if_range.split( ';')[0]
177: try: mod_since=long(DateTime(date).timeTime())
178: except: mod_since=None
179: if mod_since is not None:
180: if self._p_mtime:
181: last_mod = long(self._p_mtime)
182: else:
183: last_mod = long(0)
184: if last_mod > mod_since:
185: # Modified, so send a normal response. We delete
186: # the ranges, which causes us to skip to the 200
187: # response.
188: ranges = None
189:
190: if ranges:
191: # Search for satisfiable ranges.
192: satisfiable = 0
193: for start, end in ranges:
194: if start < self.size:
195: satisfiable = 1
196: break
197:
198: if not satisfiable:
199: RESPONSE.setHeader('Content-Range',
200: 'bytes */%d' % self.size)
201: RESPONSE.setHeader('Accept-Ranges', 'bytes')
202: RESPONSE.setHeader('Last-Modified',
203: rfc1123_date(self._p_mtime))
204: RESPONSE.setHeader('Content-Type', self.content_type)
205: RESPONSE.setHeader('Content-Length', self.size)
206: RESPONSE.setStatus(416)
207: return ''
208:
209: ranges = HTTPRangeSupport.expandRanges(ranges, self.size)
210:
211: if len(ranges) == 1:
212: # Easy case, set extra header and return partial set.
213: start, end = ranges[0]
214: size = end - start
215:
216: RESPONSE.setHeader('Last-Modified',
217: rfc1123_date(self._p_mtime))
218: RESPONSE.setHeader('Content-Type', self.content_type)
219: RESPONSE.setHeader('Content-Length', size)
220: RESPONSE.setHeader('Accept-Ranges', 'bytes')
221: RESPONSE.setHeader('Content-Range',
222: 'bytes %d-%d/%d' % (start, end - 1, self.size))
223: RESPONSE.setStatus(206) # Partial content
224:
225: data = urllib.urlopen(self.baseUrl+self.queryString).read()
226: if type(data) is StringType:
227: return data[start:end]
228:
229: # Linked Pdata objects. Urgh.
230: pos = 0
231: while data is not None:
232: l = len(data.data)
233: pos = pos + l
234: if pos > start:
235: # We are within the range
236: lstart = l - (pos - start)
237:
238: if lstart < 0: lstart = 0
239:
240: # find the endpoint
241: if end <= pos:
242: lend = l - (pos - end)
243:
244: # Send and end transmission
245: RESPONSE.write(data[lstart:lend])
246: break
247:
248: # Not yet at the end, transmit what we have.
249: RESPONSE.write(data[lstart:])
250:
251: data = data.next
252:
253: return ''
254:
255: else:
256: boundary = choose_boundary()
257:
258: # Calculate the content length
259: size = (8 + len(boundary) + # End marker length
260: len(ranges) * ( # Constant lenght per set
261: 49 + len(boundary) + len(self.content_type) +
262: len('%d' % self.size)))
263: for start, end in ranges:
264: # Variable length per set
265: size = (size + len('%d%d' % (start, end - 1)) +
266: end - start)
267:
268:
269: # Some clients implement an earlier draft of the spec, they
270: # will only accept x-byteranges.
271: draftprefix = (request_range is not None) and 'x-' or ''
272:
273: RESPONSE.setHeader('Content-Length', size)
274: RESPONSE.setHeader('Accept-Ranges', 'bytes')
275: RESPONSE.setHeader('Last-Modified',
276: rfc1123_date(self._p_mtime))
277: RESPONSE.setHeader('Content-Type',
278: 'multipart/%sbyteranges; boundary=%s' % (
279: draftprefix, boundary))
280: RESPONSE.setStatus(206) # Partial content
281:
282: data = urllib.urlopen(self.baseUrl+self.queryString).read()
283: # The Pdata map allows us to jump into the Pdata chain
284: # arbitrarily during out-of-order range searching.
285: pdata_map = {}
286: pdata_map[0] = data
287:
288: for start, end in ranges:
289: RESPONSE.write('\r\n--%s\r\n' % boundary)
290: RESPONSE.write('Content-Type: %s\r\n' %
291: self.content_type)
292: RESPONSE.write(
293: 'Content-Range: bytes %d-%d/%d\r\n\r\n' % (
294: start, end - 1, self.size))
295:
296: if type(data) is StringType:
297: RESPONSE.write(data[start:end])
298:
299: else:
300: # Yippee. Linked Pdata objects. The following
301: # calculations allow us to fast-forward through the
302: # Pdata chain without a lot of dereferencing if we
303: # did the work already.
304: first_size = len(pdata_map[0].data)
305: if start < first_size:
306: closest_pos = 0
307: else:
308: closest_pos = (
309: ((start - first_size) >> 16 << 16) +
310: first_size)
311: pos = min(closest_pos, max(pdata_map.keys()))
312: data = pdata_map[pos]
313:
314: while data is not None:
315: l = len(data.data)
316: pos = pos + l
317: if pos > start:
318: # We are within the range
319: lstart = l - (pos - start)
320:
321: if lstart < 0: lstart = 0
322:
323: # find the endpoint
324: if end <= pos:
325: lend = l - (pos - end)
326:
327: # Send and loop to next range
328: RESPONSE.write(data[lstart:lend])
329: break
330:
331: # Not yet at the end, transmit what we have.
332: RESPONSE.write(data[lstart:])
333:
334: data = data.next
335: # Store a reference to a Pdata chain link so we
336: # don't have to deref during this request again.
337: pdata_map[pos] = data
338:
339: # Do not keep the link references around.
340: del pdata_map
341:
342: RESPONSE.write('\r\n--%s--\r\n' % boundary)
343: return ''
344:
345: RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime))
346: RESPONSE.setHeader('Content-Type', self.content_type)
347: RESPONSE.setHeader('Content-Length', self.size)
348: RESPONSE.setHeader('Accept-Ranges', 'bytes')
349:
350: # Don't cache the data itself, but provide an opportunity
351: # for a cache manager to set response headers.
352: self.ZCacheable_set(None)
353:
354: data=urllib.urlopen(self.baseUrl+self.queryString).read()
355:
356: if type(data) is type(''):
357: RESPONSE.setBase(None)
358: return data
359:
360: while data is not None:
361: RESPONSE.write(data.data)
362: data=data.next
363:
364: return ''
365:
366:
367: def manage_addZogiImageForm(self):
368: """Form for adding"""
369: pt=PageTemplateFile(os.path.join(package_home(globals()), 'zpt/addZogiImage.zpt')).__of__(self)
370: return pt()
371:
372:
373: def manage_addZogiImage(self,id,title,baseUrl, queryString,RESPONSE=None):
374: """add dgilib"""
375: newObj=zogiImage(id,title,baseUrl, queryString)
376: self.Destination()._setObject(id,newObj)
377: if RESPONSE is not None:
378: RESPONSE.redirect('manage_main')
379:
380:
381:
382: class zogiLib(Folder):
383: """StandardElement"""
384:
385: meta_type="zogiLib"
386:
387: manage_options = Folder.manage_options+(
388: {'label':'Main Config','action':'changeZogiLibForm'},
389: )
390:
391: def __init__(self, id, title, digilibBaseUrl, localFileBase, version="book", basePath="", dlTarget=None):
392: """init"""
393:
394: self.id=id
395: self.title=title
396: self.digilibBaseUrl=digilibBaseUrl
397: self.localFileBase=localFileBase
398: self.basePath=basePath
399: self.layout=version
400: if dlTarget:
401: self.dlTarget = dlTarget
402: else:
403: self.dlTarget = "digilib"
404:
405: def version(self):
406: """version information"""
407: return ZOGIVERSION
408:
409: def getDLInfo(self):
410: """get DLInfo from digilib server"""
411: paramH={}
412: baseUrl=re.sub("servlet/Scaler","dlInfo-xml.jsp",self.digilibBaseUrl)
413: try:
414: url=urllib.urlopen(baseUrl+self.REQUEST['QUERY_STRING'])
415: dom=xml.dom.minidom.parse(url)
416: params=dom.getElementsByTagName('parameter')
417: for param in params:
418: paramH[param.getAttribute('name')]=param.getAttribute('value')
419: return paramH
420: except:
421: return null
422:
423:
424: def createHeadJS(self):
425: """generate all javascript tags for head"""
426: self.checkQuery()
427: bt = self.REQUEST.SESSION['browserType']
428: if bt['staticHTML']:
429: return
430:
431: pt=PageTemplateFile(os.path.join(package_home(globals()), 'zpt/zogilib_head_js')).__of__(self)
432: return pt()
433:
434: def createParamJS(self):
435: """generate javascript for parameters only"""
436: self.checkQuery()
437: bt = self.REQUEST.SESSION['browserType']
438: if bt['staticHTML']:
439: return
440:
441: pt=PageTemplateFile(os.path.join(package_home(globals()), 'zpt/zogilib_param_js')).__of__(self)
442: return pt()
443:
444:
445: def createScalerImg(self, requestString=None, bottom=0, side=0, width=500, height=500):
446: """generate Scaler IMG Tag"""
447: self.checkQuery()
448: bt = self.REQUEST.SESSION['browserType']
449: # override with parameters from session
450: if self.REQUEST.SESSION.has_key('scalerDiv'):
451: (requestString, bottom, side, width, height) = self.REQUEST.SESSION['scalerDiv']
452: # if not explicitly defined take normal request
453: if not requestString:
454: requestString = self.getAllDLParams()
455: url = self.digilibBaseUrl+requestString
456: # construct bottom and side insets
457: b_par = ""
458: s_par = ""
459: if (bottom != 0) or (side != 0):
460: b_par = "-" + str(int(bottom))
461: s_par = "-" + str(int(side))
462: tag = ""
463: if bt['staticHTML']:
464: tag += '<div id="scaler"><img id="pic" src="%s&dw=%i&dh=%i" /></div>'%(url, int(width-side), int(height-bottom))
465: else:
466: if bt['isN4']:
467: # N4 needs layers
468: tag += '<ilayer id="scaler">'
469: else:
470: tag += '<div id="scaler">'
471: tag += '<script type="text/javascript">'
472: tag += "var ps = bestPicSize(getElement('scaler'));"
473: # write img tag with javascript
474: tag += 'document.write(\'<img id="pic" src="%s&dw=\'+(ps.width%s)+\'&dh=\'+(ps.height%s)+\'" />\');'%(url, s_par, b_par)
475: tag += '</script>'
476: if bt['isN4']:
477: tag += '</ilayer>'
478: else:
479: tag += '</div>'
480: return tag
481:
482: def createScalerDiv(self, requestString = None, bottom = 0, side = 0, width=500, height=500):
483: """generate scaler img and table with navigation arrows"""
484: self.checkQuery()
485: if requestString != None or bottom != 0 or side != 0:
486: self.REQUEST.SESSION['scalerDiv'] = (requestString, bottom, side, width, height)
487: else:
488: if self.REQUEST.SESSION.has_key('scalerDiv'):
489: # make shure to remove unused parameter
490: del self.REQUEST.SESSION['scalerDiv']
491:
492: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/zogilib_img_div')).__of__(self)
493: return pt()
494:
495: def createAuxDiv(self):
496: """generate other divs"""
497: self.checkQuery()
498: bt = self.REQUEST.SESSION['browserType']
499: if bt['staticHTML']:
500: return
501: if bt['isN4']:
502: f = 'zpt/zogilib_divsN4.zpt'
503: else:
504: f = 'zpt/zogilib_divs.zpt'
505: pt=PageTemplateFile(os.path.join(package_home(globals()),f)).__of__(self)
506: return pt()
507:
508:
509: def option_js(self):
510: """javascript"""
511: return sendFile(self, 'js/option.js', 'text/plain')
512:
513: def dl_lib_js(self):
514: """javascript"""
515: return sendFile(self, 'js/dl_lib.js', 'text/plain')
516:
517: def js_lib_js(self):
518: """javascript"""
519: return sendFile(self, 'js/js_lib.js', 'text/plain')
520:
521: def optionwindow(self):
522: """showoptions"""
523: self.checkQuery()
524: bt = self.REQUEST.SESSION['browserType']
525: if bt['staticHTML']:
526: pt=PageTemplateFile(os.path.join(package_home(globals()), 'zpt/optionwindow_static.zpt')).__of__(self)
527: else:
528: finds=self.ZopeFind(self,obj_ids=['viewingTools.zpt'])
529: if finds:
530:
531: return finds[0][1]()
532: else:
533: pt=PageTemplateFile(os.path.join(package_home(globals()), 'zpt/optionwindow.zpt')).__of__(self)
534: return pt()
535:
536: def mark1(self):
537: """mark image"""
538: return sendFile(self, 'images/mark1.gif', 'image/gif')
539:
540: def mark2(self):
541: """mark image"""
542: return sendFile(self, 'images/mark2.gif', 'image/gif')
543:
544: def mark3(self):
545: """mark image"""
546: return sendFile(self, 'images/mark3.gif', 'image/gif')
547:
548: def mark4(self):
549: """mark image"""
550: return sendFile(self, 'images/mark4.gif', 'image/gif')
551:
552: def mark5(self):
553: """mark image"""
554: return sendFile(self, 'images/mark5.gif', 'image/gif')
555:
556: def mark6(self):
557: """mark image"""
558: return sendFile(self, 'images/mark6.gif', 'image/gif')
559:
560: def mark7(self):
561: """mark image"""
562: return sendFile(self, 'images/mark7.gif', 'image/gif')
563:
564: def mark8(self):
565: """mark image"""
566: return sendFile(self, 'images/mark8.gif', 'image/gif')
567:
568: def corner1(self):
569: """mark image"""
570: return sendFile(self, 'images/olinks.gif', 'image/gif')
571:
572: def corner2(self):
573: """mark image"""
574: return sendFile(self, 'images/orechts.gif', 'image/gif')
575:
576: def corner3(self):
577: """mark image"""
578: return sendFile(self, 'images/ulinks.gif', 'image/gif')
579:
580: def corner4(self):
581: """mark image"""
582: return sendFile(self, 'images/urechts.gif', 'image/gif')
583:
584: def up_img(self):
585: """mark image"""
586: return sendFile(self, 'images/up.gif', 'image/gif')
587:
588: def down_img(self):
589: """mark image"""
590: return sendFile(self, 'images/down.gif', 'image/gif')
591:
592: def left_img(self):
593: """mark image"""
594: return sendFile(self, 'images/left.gif', 'image/gif')
595:
596: def right_img(self):
597: """mark image"""
598: return sendFile(self, 'images/right.gif', 'image/gif')
599:
600:
601:
602: def index_html(self):
603: """main action"""
604: self.checkQuery()
605: bt = self.REQUEST.SESSION['browserType']
606: tp = "zogiLibMainTemplate"
607: if hasattr(self, tp):
608: pt = getattr(self, tp)
609: else:
610: tpt = self.layout
611: if bt['staticHTML']:
612: tpt = "static"
613:
614: pt=PageTemplateFile(os.path.join(package_home(globals()), 'zpt/zogiLibMain_%s'%tpt)).__of__(self)
615:
616: return pt()
617:
618:
619:
620: def storeQuery(self, more = None):
621: """storeQuery in session"""
622: dlParams = {}
623: for fm in self.REQUEST.form.keys():
624: dlParams[fm] = self.REQUEST.form[fm]
625: # look for more
626: if more:
627: for fm in more.split('&'):
628: try:
629: pv = fm.split('=')
630: dlParams[pv[0]] = pv[1]
631: except:
632: pass
633:
634: # parse digilib mode parameter
635: if 'mo' in dlParams:
636: if len(dlParams['mo']) > 0:
637: modes=dlParams['mo'].split(',')
638: else:
639: modes=[]
640:
641: self.REQUEST.SESSION['query'] = dlParams
642: self.REQUEST.SESSION['dlModes'] = modes
643: self.REQUEST.SESSION['dlInfo'] = self.getDLInfo()
644: if not self.REQUEST.SESSION.has_key('browserType'):
645: self.REQUEST.SESSION['browserType'] = browserCheck(self)
646:
647: return
648:
649: def checkQuery(self):
650: """check if the query has been stored"""
651: if not (self.REQUEST.SESSION and self.REQUEST.SESSION.has_key('query')) :
652: print "ZOGILIB: have to store query!!"
653: self.storeQuery()
654: return
655:
656: def zogilibPath(self, otherbase=None):
657: """returns an URL to the zogiLib instance"""
658: url = self.REQUEST['URL1']
659: # should end with "/"
660: if len(url) > 0 and url[-1] != '/':
661: url += '/'
662: if type(otherbase) is str:
663: url += otherbase
664: else:
665: url += self.basePath
666: # should end with "/"
667: if len(url) > 0 and url[-1] != '/':
668: url += '/'
669: return url
670:
671: def getDLParam(self, param):
672: """returns parameter"""
673: try:
674: return self.REQUEST.SESSION['query'][param]
675: except:
676: return
677:
678: def setDLParam(self, param, value):
679: """sets parameter"""
680: self.REQUEST.SESSION['query'][param] = value
681: return
682:
683: def getAllDLParams(self):
684: """parameter string for digilib"""
685: dlParams = self.REQUEST.SESSION['query']
686: # save modes
687: modes = self.REQUEST.SESSION['dlModes']
688: dlParams['mo'] = string.join(modes, ',')
689: # assemble query string
690: ret = ""
691: for param in dlParams.keys():
692: if dlParams[param] is None: continue
693: val = str(dlParams[param])
694: if val != "":
695: ret += param + "=" + val + "&"
696:
697: # omit trailing "&"
698: return ret.rstrip('&')
699:
700:
701: def setDLParams(self,pn=None,ws=None,rot=None,brgt=None,cont=None):
702: """setze Parameter"""
703:
704: self.setDLParam('brgt', brgt)
705: self.setDLParam('cont', cont)
706: self.setDLParam('ws', ws)
707: self.setDLParam('rot', rot)
708:
709: if pn:
710: # unmark
711: self.setDLParam('mk', None)
712: self.setDLParam('pn', pn)
713:
714: return self.display()
715:
716:
717: def display(self):
718: """(re)display page"""
719: params = self.getAllDLParams()
720: if self.basePath:
721: self.REQUEST.RESPONSE.redirect(self.REQUEST['URL2']+'?'+params)
722: else:
723: self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+'?'+params)
724:
725:
726: def getDLTarget(self):
727: """returns dlTarget"""
728: self.checkQuery()
729: s = self.dlTarget
730: # s = 'dl'
731: # if self.getDLParam('fn'):
732: # s += "_" + self.getDLParam('fn')
733: # if self.getDLParam('pn'):
734: # s += "_" + self.getDLParam('pn')
735: return s
736:
737: def setStaticHTML(self, static=True):
738: """sets the preference to static HTML"""
739: self.checkQuery()
740: self.REQUEST.SESSION['browserType']['staticHTML'] = static
741: return
742:
743: def isStaticHTML(self):
744: """returns if the page is using static HTML only"""
745: self.checkQuery()
746: return self.REQUEST.SESSION['browserType']['staticHTML']
747:
748: def getPT(self):
749: """pagenums"""
750: di = self.REQUEST.SESSION['dlInfo']
751: if di:
752: return int(di['pt'])
753: else:
754: return 1
755:
756: def getPN(self):
757: """Pagenum"""
758: pn = self.getDLParam('pn')
759: try:
760: return int(pn)
761: except:
762: return 1
763:
764: def getBiggerWS(self):
765: """ws+1"""
766: ws = self.getDLParam('ws')
767: try:
768: return float(ws)+0.5
769: except:
770: return 1.5
771:
772: def getSmallerWS(self):
773: """ws-1"""
774: ws=self.getDLParam('ws')
775: try:
776: return max(float(ws)-0.5, 1)
777: except:
778: return 1
779:
780: def hasMode(self, mode):
781: """returns if mode is in the diglib mo parameter"""
782: return (mode in self.REQUEST.SESSION['dlModes'])
783:
784: def hasNextPage(self):
785: """returns if there is a next page"""
786: pn = self.getPN()
787: pt = self.getPT()
788: return (pn < pt)
789:
790: def hasPrevPage(self):
791: """returns if there is a previous page"""
792: pn = self.getPN()
793: return (pn > 1)
794:
795: def canMoveLeft(self):
796: """returns if its possible to move left"""
797: wx = float(self.getDLParam('wx') or 0)
798: return (wx > 0)
799:
800: def canMoveRight(self):
801: """returns if its possible to move right"""
802: wx = float(self.getDLParam('wx') or 0)
803: ww = float(self.getDLParam('ww') or 1)
804: return (wx + ww < 1)
805:
806: def canMoveUp(self):
807: """returns if its possible to move up"""
808: wy = float(self.getDLParam('wy') or 0)
809: return (wy > 0)
810:
811: def canMoveDown(self):
812: """returns if its possible to move down"""
813: wy = float(self.getDLParam('wy') or 0)
814: wh = float(self.getDLParam('wh') or 1)
815: return (wy + wh < 1)
816:
817:
818: def dl_StaticHTML(self):
819: """set rendering to static HTML"""
820: self.checkQuery()
821: self.REQUEST.SESSION['browserType']['staticHTML'] = True
822: return self.display()
823:
824: def dl_DynamicHTML(self):
825: """set rendering to dynamic HTML"""
826: self.checkQuery()
827: self.REQUEST.SESSION['browserType']['staticHTML'] = False
828: return self.display()
829:
830: def dl_HMirror(self):
831: """mirror action"""
832: modes = self.REQUEST.SESSION['dlModes']
833: if 'hmir' in modes:
834: modes.remove('hmir')
835: else:
836: modes.append('hmir')
837:
838: return self.display()
839:
840: def dl_VMirror(self):
841: """mirror action"""
842: modes = self.REQUEST.SESSION['dlModes']
843: if 'vmir' in modes:
844: modes.remove('vmir')
845: else:
846: modes.append('vmir')
847:
848: return self.display()
849:
850: def dl_Zoom(self, z):
851: """general zoom action"""
852: ww1 = float(self.getDLParam('ww') or 1)
853: wh1 = float(self.getDLParam('wh') or 1)
854: wx = float(self.getDLParam('wx') or 0)
855: wy = float(self.getDLParam('wy') or 0)
856: ww2 = ww1 * z
857: wh2 = wh1 * z
858: wx += (ww1 - ww2) / 2
859: wy += (wh1 - wh2) / 2
860: ww2 = max(min(ww2, 1), 0)
861: wh2 = max(min(wh2, 1), 0)
862: wx = max(min(wx, 1), 0)
863: wy = max(min(wy, 1), 0)
864: self.setDLParam('ww', cropf(ww2))
865: self.setDLParam('wh', cropf(wh2))
866: self.setDLParam('wx', cropf(wx))
867: self.setDLParam('wy', cropf(wy))
868: return self.display()
869:
870: def dl_ZoomIn(self):
871: """zoom in action"""
872: z = 0.7071
873: return self.dl_Zoom(z)
874:
875: def dl_ZoomOut(self):
876: """zoom out action"""
877: z = 1.4142
878: return self.dl_Zoom(z)
879:
880: def dl_Move(self, dx, dy):
881: """general move action"""
882: ww = float(self.getDLParam('ww') or 1)
883: wh = float(self.getDLParam('wh') or 1)
884: wx = float(self.getDLParam('wx') or 0)
885: wy = float(self.getDLParam('wy') or 0)
886: wx += dx * 0.5 * ww
887: wy += dy * 0.5 * wh
888: wx = max(min(wx, 1), 0)
889: wy = max(min(wy, 1), 0)
890: self.setDLParam('wx', cropf(wx))
891: self.setDLParam('wy', cropf(wy))
892: return self.display()
893:
894: def dl_MoveLeft(self):
895: """move left action"""
896: return self.dl_Move(-1, 0)
897:
898: def dl_MoveRight(self):
899: """move left action"""
900: return self.dl_Move(1, 0)
901:
902: def dl_MoveUp(self):
903: """move left action"""
904: return self.dl_Move(0, -1)
905:
906: def dl_MoveDown(self):
907: """move left action"""
908: return self.dl_Move(0, 1)
909:
910: def dl_WholePage(self):
911: """zoom out action"""
912: self.setDLParam('ww', 1)
913: self.setDLParam('wh', 1)
914: self.setDLParam('wx', 0)
915: self.setDLParam('wy', 0)
916: return self.display()
917:
918: def dl_PrevPage(self):
919: """next page action"""
920: pn = self.getPN() - 1
921: if pn < 1:
922: pn = 1
923: self.setDLParam('pn', pn)
924: # unmark
925: self.setDLParam('mk', None)
926: return self.display()
927:
928: def dl_NextPage(self):
929: """next page action"""
930: pn = self.getPN() + 1
931: pt = self.getPT()
932: if pn > pt:
933: pn = pt
934: self.setDLParam('pn', pn)
935: # unmark
936: self.setDLParam('mk', None)
937: return self.display()
938:
939: def dl_FirstPage(self):
940: """first page action"""
941: self.setDLParam('pn', 1)
942: # unmark
943: self.setDLParam('mk', None)
944: return self.display()
945:
946: def dl_LastPage(self):
947: """last page action"""
948: self.setDLParam('pn', self.getPT())
949: # unmark
950: self.setDLParam('mk', None)
951: return self.display()
952:
953: def dl_Unmark(self):
954: """action to remove last mark"""
955: mk = self.getDLParam('mk')
956: if mk:
957: marks = mk.split(',')
958: marks.pop()
959: mk = string.join(marks, ',')
960: self.setDLParam('mk', mk)
961: return self.display()
962:
963:
964:
965: def changeZogiLibForm(self):
966: """Main configuration"""
967: pt=PageTemplateFile(os.path.join(package_home(globals()), 'zpt/changeZogiLibForm.zpt')).__of__(self)
968: return pt()
969:
970: def changeZogiLib(self,title,digilibBaseUrl, localFileBase, version, basePath, dlTarget, RESPONSE=None):
971: """change it"""
972: self.title=title
973: self.digilibBaseUrl=digilibBaseUrl
974: self.localFileBase=localFileBase
975: self.basePath = basePath
976: self.layout=version
977: if dlTarget:
978: self.dlTarget = dlTarget
979: else:
980: self.dlTarget = "digilib"
981:
982: if RESPONSE is not None:
983: RESPONSE.redirect('manage_main')
984:
985:
986: def manage_addZogiLibForm(self):
987: """interface for adding zogilib"""
988: pt=PageTemplateFile(os.path.join(package_home(globals()), 'zpt/addZogiLibForm')).__of__(self)
989: return pt()
990:
991: def manage_addZogiLib(self,id,title,digilibBaseUrl, localFileBase,version="book",basePath="",dlTarget="digilib",RESPONSE=None):
992: """add dgilib"""
993: newObj=zogiLib(id,title,digilibBaseUrl, localFileBase, version, basePath, dlTarget)
994: self.Destination()._setObject(id,newObj)
995: if RESPONSE is not None:
996: RESPONSE.redirect('manage_main')
997:
998:
999: class zogiLibPageTemplate(ZopePageTemplate):
1000: """pageTemplate Objekt"""
1001: meta_type="zogiLib_pageTemplate"
1002:
1003:
1004: ## def __init__(self, id, text=None, contentType=None):
1005: ## self.id = str(id)
1006: ## self.ZBindings_edit(self._default_bindings)
1007: ## if text is None:
1008: ## text = open(self._default_cont).read()
1009: ## self.pt_edit(text, contentType)
1010:
1011: def manage_addZogiLibPageTemplateForm(self):
1012: """Form for adding"""
1013: pt=PageTemplateFile(os.path.join(package_home(globals()), 'zpt/addZogiLibPageTemplateForm')).__of__(self)
1014: return pt()
1015:
1016: def manage_addZogiLibPageTemplate(self, id='zogiLibMainTemplate', title=None, layout=None, text=None,
1017: REQUEST=None, submit=None):
1018: "Add a Page Template with optional file content."
1019:
1020: id = str(id)
1021: self._setObject(id, zogiLibPageTemplate(id))
1022: ob = getattr(self, id)
1023: if not layout: layout = "book"
1024: ob.pt_edit(open(os.path.join(package_home(globals()),'zpt/zogiLibMain_%s.zpt'%layout)).read(),None)
1025: if title:
1026: ob.pt_setTitle(title)
1027: try:
1028: u = self.DestinationURL()
1029: except AttributeError:
1030: u = REQUEST['URL1']
1031:
1032: u = "%s/%s" % (u, urllib.quote(id))
1033: REQUEST.RESPONSE.redirect(u+'/manage_main')
1034: return ''
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>