File:  [Repository] / zogiLib / zogiLib.py
Revision 1.27: download - view: text, annotated - select for diffs - revision graph
Mon Jun 21 16:19:56 2004 UTC (20 years, 1 month ago) by casties
Branches: MAIN
CVS tags: HEAD
fix for setting window.name when in frame
new parameter dlTarget

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

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