from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.PageTemplates.PageTemplate import PageTemplate
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
from OFS.Image import Image
from webdav.common import rfc1123_date
import xml.dom.minidom
from OFS.Folder import Folder
from xml_helpers import getText
import os
import re
import string
import urllib
from Globals import package_home
def getString(self,key,default=''):
try:
return self.REQUEST[key]
except:
return default
class zogiLib_navTemplate(ZopePageTemplate):
"""pageTemplate Objekt"""
meta_type="zogiLib_navTemplate"
_default_content_fn = os.path.join(package_home(globals()),
'zpt/zogiLib_NavTemplateDefault.zpt')
manage_options=ZopePageTemplate.manage_options+(
{'label':'Copy to Filesystem','action':'copyContent'},
)
def getPath(self):
"""get path"""
return getPath(self,'thumbtemplate.templ')
def copyContent(self):
"""copycontent to path"""
return "copied to:"+copyContent(self,'thumbtemplate.templ')
def manage_addZogiLib_NavTemplateForm(self):
"""Form for adding"""
pt=PageTemplateFile('Products/zogiLib/zpt/AddZogilib_NavTemplate.zpt').__of__(self)
return pt()
def manage_addZogiLib_NavTemplate(self, id,title=None, text=None,
REQUEST=None, submit=None):
"Add a Page Template with optional file content."
id = str(id)
if REQUEST is None:
self._setObject(id, zogilib_NavTemplate(id, text))
ob = getattr(self, id)
if title:
ob.pt_setTitle(title)
return ob
else:
file = REQUEST.form.get('file')
headers = getattr(file, 'headers', None)
if headers is None or not file.filename:
zpt = zogilib_NavTemplate(id)
else:
zpt = zogilib_NavTemplate(id, file, headers.get('content_type'))
self._setObject(id, zpt)
ob = getattr(self, id)
try:
u = self.DestinationURL()
except AttributeError:
u = REQUEST['URL1']
if submit == " Add and Edit ":
u = "%s/%s" % (u, quote(id))
REQUEST.RESPONSE.redirect(u+'/manage_main')
return ''
def readNavTemp(fileName):
"""navtemp"""
if os.path.exists(fileName+"/index.meta"):
dom=xml.dom.minidom.parse(fileName+"/index.meta")
else:
return None
try:
navTag=getText(dom.getElementsByTagName('zogilibtemplate')[0].childNodes)
except:
navTag=None
return navTag
class zogiLib_mainTemplate(ZopePageTemplate):
"""pageTemplate Objekt"""
meta_type="zogiLib_mainTemplate"
def __init__(self, id, text=None, content_type=None, version="book"):
default_content_string="zpt/zogiLibMain_%s.zpt"%version
self._default_content_fn = os.path.join(package_home(globals()),default_content_string)
self.id = str(id)
self.ZBindings_edit(self._default_bindings)
if text is None:
text = open(self._default_content_fn).read()
self.pt_edit(text, content_type)
def manage_addZogiLibMainTemplateForm(self):
"""Form for adding"""
pt=PageTemplateFile('Products/ECHO_content/zpt/AddOSAS_thumbTemplate.zpt').__of__(self)
return pt()
def manage_addZogiLibMainTemplate(self, id,title=None, text=None,
REQUEST=None, submit=None):
"Add a Page Template with optional file content."
id = str(id)
if REQUEST is None:
self._setObject(id, zogiLib_mainTemplate(id, text))
ob = getattr(self, id)
if title:
ob.pt_setTitle(title)
return ob
else:
file = REQUEST.form.get('file')
headers = getattr(file, 'headers', None)
if headers is None or not file.filename:
zpt = zogiLib_mainTemplate(id)
else:
zpt = zogiLib_mainTemplate(id, file, headers.get('content_type'))
self._setObject(id, zpt)
ob = getattr(self, id)
try:
u = self.DestinationURL()
except AttributeError:
u = REQUEST['URL1']
if submit == " Add and Edit ":
u = "%s/%s" % (u, quote(id))
REQUEST.RESPONSE.redirect(u+'/manage_main')
return ''
class zogiImage(Image):
"""einzelnes Image"""
meta_type="zogiImage"
def __init__(self,id,title,baseUrl,queryString,content_type='',precondition=''):
"""init"""
self.id=id
self.title=title
self.baseUrl=baseUrl
self.queryString=queryString
self.content_type=content_type
self.precondition=precondition
def getData(self):
"""getUrlData"""
return urllib.urlopen(self.baseUrl+self.queryString)
def changeZogiImageForm(self):
"""Main configuration"""
pt=PageTemplateFile('Products/zogiLib/zpt/changeZogiImageForm.zpt').__of__(self)
return pt()
def changeZogiImage(self,title,baseUrl, queryString,RESPONSE=None):
"""change it"""
self.title=title
self.baseUrl=baseUrl
self.queryString=queryString
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
manage_options=ZopePageTemplate.manage_options+(
{'label':'Main config','action':'changeZogiImageForm'},
)
def index_html(self, REQUEST, RESPONSE):
"""
Modified version of OFS/Image.py
The default view of the contents of a File or Image.
Returns the contents of the file or image. Also, sets the
Content-Type HTTP header to the objects content type.
"""
# HTTP If-Modified-Since header handling.
header=REQUEST.get_header('If-Modified-Since', None)
if header is not None:
header=header.split( ';')[0]
# Some proxies seem to send invalid date strings for this
# header. If the date string is not valid, we ignore it
# rather than raise an error to be generally consistent
# with common servers such as Apache (which can usually
# understand the screwy date string as a lucky side effect
# of the way they parse it).
# This happens to be what RFC2616 tells us to do in the face of an
# invalid date.
try: mod_since=long(DateTime(header).timeTime())
except: mod_since=None
if mod_since is not None:
if self._p_mtime:
last_mod = long(self._p_mtime)
else:
last_mod = long(0)
if last_mod > 0 and last_mod <= mod_since:
# Set header values since apache caching will return Content-Length
# of 0 in response if size is not set here
RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime))
RESPONSE.setHeader('Content-Type', self.content_type)
RESPONSE.setHeader('Content-Length', self.size)
RESPONSE.setHeader('Accept-Ranges', 'bytes')
self.ZCacheable_set(None)
RESPONSE.setStatus(304)
return ''
if self.precondition and hasattr(self,self.precondition):
# Grab whatever precondition was defined and then
# execute it. The precondition will raise an exception
# if something violates its terms.
c=getattr(self,self.precondition)
if hasattr(c,'isDocTemp') and c.isDocTemp:
c(REQUEST['PARENTS'][1],REQUEST)
else:
c()
# HTTP Range header handling
range = REQUEST.get_header('Range', None)
request_range = REQUEST.get_header('Request-Range', None)
if request_range is not None:
# Netscape 2 through 4 and MSIE 3 implement a draft version
# Later on, we need to serve a different mime-type as well.
range = request_range
if_range = REQUEST.get_header('If-Range', None)
if range is not None:
ranges = HTTPRangeSupport.parseRange(range)
if if_range is not None:
# Only send ranges if the data isn't modified, otherwise send
# the whole object. Support both ETags and Last-Modified dates!
if len(if_range) > 1 and if_range[:2] == 'ts':
# ETag:
if if_range != self.http__etag():
# Modified, so send a normal response. We delete
# the ranges, which causes us to skip to the 200
# response.
ranges = None
else:
# Date
date = if_range.split( ';')[0]
try: mod_since=long(DateTime(date).timeTime())
except: mod_since=None
if mod_since is not None:
if self._p_mtime:
last_mod = long(self._p_mtime)
else:
last_mod = long(0)
if last_mod > mod_since:
# Modified, so send a normal response. We delete
# the ranges, which causes us to skip to the 200
# response.
ranges = None
if ranges:
# Search for satisfiable ranges.
satisfiable = 0
for start, end in ranges:
if start < self.size:
satisfiable = 1
break
if not satisfiable:
RESPONSE.setHeader('Content-Range',
'bytes */%d' % self.size)
RESPONSE.setHeader('Accept-Ranges', 'bytes')
RESPONSE.setHeader('Last-Modified',
rfc1123_date(self._p_mtime))
RESPONSE.setHeader('Content-Type', self.content_type)
RESPONSE.setHeader('Content-Length', self.size)
RESPONSE.setStatus(416)
return ''
ranges = HTTPRangeSupport.expandRanges(ranges, self.size)
if len(ranges) == 1:
# Easy case, set extra header and return partial set.
start, end = ranges[0]
size = end - start
RESPONSE.setHeader('Last-Modified',
rfc1123_date(self._p_mtime))
RESPONSE.setHeader('Content-Type', self.content_type)
RESPONSE.setHeader('Content-Length', size)
RESPONSE.setHeader('Accept-Ranges', 'bytes')
RESPONSE.setHeader('Content-Range',
'bytes %d-%d/%d' % (start, end - 1, self.size))
RESPONSE.setStatus(206) # Partial content
data = urllib.urlopen(self.baseUrl+self.queryString).read()
if type(data) is StringType:
return data[start:end]
# Linked Pdata objects. Urgh.
pos = 0
while data is not None:
l = len(data.data)
pos = pos + l
if pos > start:
# We are within the range
lstart = l - (pos - start)
if lstart < 0: lstart = 0
# find the endpoint
if end <= pos:
lend = l - (pos - end)
# Send and end transmission
RESPONSE.write(data[lstart:lend])
break
# Not yet at the end, transmit what we have.
RESPONSE.write(data[lstart:])
data = data.next
return ''
else:
boundary = choose_boundary()
# Calculate the content length
size = (8 + len(boundary) + # End marker length
len(ranges) * ( # Constant lenght per set
49 + len(boundary) + len(self.content_type) +
len('%d' % self.size)))
for start, end in ranges:
# Variable length per set
size = (size + len('%d%d' % (start, end - 1)) +
end - start)
# Some clients implement an earlier draft of the spec, they
# will only accept x-byteranges.
draftprefix = (request_range is not None) and 'x-' or ''
RESPONSE.setHeader('Content-Length', size)
RESPONSE.setHeader('Accept-Ranges', 'bytes')
RESPONSE.setHeader('Last-Modified',
rfc1123_date(self._p_mtime))
RESPONSE.setHeader('Content-Type',
'multipart/%sbyteranges; boundary=%s' % (
draftprefix, boundary))
RESPONSE.setStatus(206) # Partial content
data = urllib.urlopen(self.baseUrl+self.queryString).read()
# The Pdata map allows us to jump into the Pdata chain
# arbitrarily during out-of-order range searching.
pdata_map = {}
pdata_map[0] = data
for start, end in ranges:
RESPONSE.write('\r\n--%s\r\n' % boundary)
RESPONSE.write('Content-Type: %s\r\n' %
self.content_type)
RESPONSE.write(
'Content-Range: bytes %d-%d/%d\r\n\r\n' % (
start, end - 1, self.size))
if type(data) is StringType:
RESPONSE.write(data[start:end])
else:
# Yippee. Linked Pdata objects. The following
# calculations allow us to fast-forward through the
# Pdata chain without a lot of dereferencing if we
# did the work already.
first_size = len(pdata_map[0].data)
if start < first_size:
closest_pos = 0
else:
closest_pos = (
((start - first_size) >> 16 << 16) +
first_size)
pos = min(closest_pos, max(pdata_map.keys()))
data = pdata_map[pos]
while data is not None:
l = len(data.data)
pos = pos + l
if pos > start:
# We are within the range
lstart = l - (pos - start)
if lstart < 0: lstart = 0
# find the endpoint
if end <= pos:
lend = l - (pos - end)
# Send and loop to next range
RESPONSE.write(data[lstart:lend])
break
# Not yet at the end, transmit what we have.
RESPONSE.write(data[lstart:])
data = data.next
# Store a reference to a Pdata chain link so we
# don't have to deref during this request again.
pdata_map[pos] = data
# Do not keep the link references around.
del pdata_map
RESPONSE.write('\r\n--%s--\r\n' % boundary)
return ''
RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime))
RESPONSE.setHeader('Content-Type', self.content_type)
RESPONSE.setHeader('Content-Length', self.size)
RESPONSE.setHeader('Accept-Ranges', 'bytes')
# Don't cache the data itself, but provide an opportunity
# for a cache manager to set response headers.
self.ZCacheable_set(None)
data=urllib.urlopen(self.baseUrl+self.queryString).read()
if type(data) is type(''):
RESPONSE.setBase(None)
return data
while data is not None:
RESPONSE.write(data.data)
data=data.next
return ''
def manage_addZogiImageForm(self):
"""Form for adding"""
pt=PageTemplateFile('Products/zogiLib/zpt/addZogiImage.zpt').__of__(self)
return pt()
def manage_addZogiImage(self,id,title,baseUrl, queryString,RESPONSE=None):
"""add dgilib"""
newObj=zogiImage(id,title,baseUrl, queryString)
self.Destination()._setObject(id,newObj)
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
class zogiLib(Folder):
"""StandardElement"""
meta_type="zogiLib"
def getDlInfo(self):
"""DLInfo"""
paramH={}
baseUrl=re.sub("servlet/Scaler","dlInfo-xml.jsp",self.digilibBaseUrl)
url=urllib.urlopen(baseUrl+self.REQUEST['QUERY_STRING'])
dom=xml.dom.minidom.parse(url)
params=dom.getElementsByTagName('parameter')
for param in params:
paramH[param.getAttribute('name')]=param.getAttribute('value')
return paramH
def getPageNumTotal(self):
"""pagenums"""
return self.getDlInfo()['pt'].encode('utf-8')
def generateImageFolder(self):
"""images ablegen"""
self.manage_addFolder('images')
pathName=os.path.join(package_home(globals()),'images')
for image in os.listdir(pathName):
try:
fn=file(os.path.join(pathName,image))
self.images.manage_addImage(image,fn)
except:
print "ZOGILIB not imported:",image
def __init__(self, id,title,digilibBaseUrl, localFileBase,version="book"):
"""init"""
self.id=id
self.title=title
self.digilibBaseUrl=digilibBaseUrl
self.localFileBase=localFileBase
#self._setObject('topTemplate',zogiLib_navTemplate(id='topTemplate'))
self._setObject('mainTemplate',zogiLib_mainTemplate(id='mainTemplate',version=version))
self.generateImageFolder()
manage_options = Folder.manage_options+(
{'label':'Main Config','action':'changeZogiLibForm'},
)
def option_js(self):
"""option_js"""
ret="""function setDLParam(e) {
if (document.all) {
s=e.srcElement;
} else {
s=e.target;
}
if (window.opener) {
window.opener.setParameter(s.name, s.value);
window.opener.display(9);
} else {
setParameter(s.name, s.value);
display(9);
}
}"""
return ret
def navigation_js(self):
"""Javascript"""
fileName=os.path.join(package_home(globals()),'js/navigation.js')
return file(fileName).read()
def generateTopJavaScript(self):
"""generate script"""
ret="""
var baseUrl = '%s'; """% self.REQUEST['URL0']
ret+="""
newParameter('fn', '', 1);
newParameter('pn', '1', 1);
newParameter('ws', '1.0', 1);
newParameter('mo', '', 1);
newParameter('mk', '', 3);
newParameter('wx', '0.0', 2);
newParameter('wy', '0.0', 2);
newParameter('ww', '1.0', 2);
newParameter('wh', '1.0', 2);
newParameter('pt', '0', 9);
newParameter('brgt', '0.0', 1);
newParameter('cont', '0.0', 1);
newParameter('rot', '0.0', 1);
newParameter('rgba', '', 1);
newParameter('rgbm', '', 1);
newParameter('ddpix', '', 9);
newParameter('ddpiy', '', 9);
var picsize = new Size(100, 100);
document.id='digilib';
"""
return ret
def generateScalerImg(self,requestString):
"""generate Scaler IMG Tag"""
retStr=self.digilibBaseUrl+requestString
jS="""<script type="text/javascript">var ps = bestPicSize('scaler');
document.write('<img id="pic" src="%s&dw='+ps.width+'&dh='+ps.height+'" />')
</script>"""%retStr
return jS
def changeZogiLibForm(self):
"""Main configuration"""
pt=PageTemplateFile('Products/zogiLib/zpt/changeZogiLibForm.zpt').__of__(self)
return pt()
def changeZogiLib(self,title,digilibBaseUrl, localFileBase,RESPONSE=None):
"""change it"""
self.title=title
self.digilibBaseUrl=digilibBaseUrl
self.localFileBase=localFileBase
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
def nav_html(self,fileName):
"""navigations frame"""
## currently not in use
# suche nach index.meta mit zogilib thumb info
templ=readNavTemp(self.localFileBase+"/"+fileName)
if not templ:
templ=readNavTemp(self.localFileBase+"/"+fileName.split("/")[0])
if not templ:
return self.topTemplate.document_src()
return urllib.urlopen(templ).read()
def index_html(self):
"""main action"""
#pt=PageTemplateFile('Products/zogiLib/zpt/zogiLibMain_image.zpt').__of__(self)
#return pt()
return self.mainTemplate()
def storeQuery(self):
"""storeQuery in session"""
self.REQUEST.SESSION['query']={}
for fm in self.REQUEST.form.keys():
self.REQUEST.SESSION['query'][fm]=self.REQUEST.form[fm]
self.REQUEST.SESSION['dlInfo']=self.getDlInfo()
def getParam(self,param):
"""Gebe Parameter aus"""
try:
return self.REQUEST.SESSION['query'][param]
except:
return None
def getPageNum(self):
"""PAgenum"""
pn=self.getParam('pn')
if pn:
return pn
else:
return 1
def biggerWS(self):
"""ws+1"""
ws=self.getParam('ws')
if ws:
return int(ws)+1
else:
return 2
def options(self):
"""showoptions"""
pt=PageTemplateFile('Products/zogiLib/zpt/optionwindow.zpt').__of__(self)
return pt()
def smallerWS(self):
"""ws-11"""
ws=self.getParam('ws')
if ws:
if int(ws)==1:
return
else:
return int(ws)-1
else:
return 1
def setParam(self,pn=None,ws=None,rot=None,brgt=None,cont=None):
"""setze Parameter"""
ret=""
if brgt:
self.REQUEST.SESSION['query']['brgt']=brgt
if cont:
self.REQUEST.SESSION['query']['cont']=cont
if pn:
self.REQUEST.SESSION['query']['pn']=pn
if ws:
self.REQUEST.SESSION['query']['ws']=ws
if rot:
self.REQUEST.SESSION['query']['rot']=rot
for param in self.REQUEST.SESSION['query'].keys():
ret+=param+"="+str(self.REQUEST.SESSION['query'][param])+"&"
self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+'?'+ret)
def mirrorPage(self,mi):
"""mirror"""
ret=""
try:
splitted=self.REQUEST.SESSION['query']['mo'].split(',')
except:
splitted=[]
if mi=="h":
if 'hmir' in splitted:
splitted.remove('hmir')
else:
splitted.append('hmir')
if mi=="v":
if 'vmir' in splitted:
splitted.remove('vmir')
else:
splitted.append('vmir')
self.REQUEST.SESSION['query']['mo']=string.join(splitted,",")
for param in self.REQUEST.SESSION['query'].keys():
ret+=param+"="+str(self.REQUEST.SESSION['query'][param])+"&"
self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+'?'+ret)
def decode(self,strR):
"""decode &"""
return re.sub('\&','\&',strR)
def wholePage(self):
"""zoom out"""
ret=""
self.REQUEST.SESSION['query']['ww']=1
self.REQUEST.SESSION['query']['wh']=1
self.REQUEST.SESSION['query']['wx']=0
self.REQUEST.SESSION['query']['wy']=0
for param in self.REQUEST.SESSION['query'].keys():
ret+=param+"="+str(self.REQUEST.SESSION['query'][param])+"&"
self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+'?'+ret)
def prevPage(self,pn=None):
"""next page"""
ret=""
if pn and pn>0:
pn=str(int(pn)-1)
self.REQUEST.form['pn']=pn
for param in self.REQUEST.form.keys():
ret+=param+"="+str(self.REQUEST.form[param])+"&"
self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+'?'+ret)
def firstPage(self):
"""erste Seite"""
return self.setParam(pn="1")
def lastPage(self):
"""letzte Seite"""
def nextPage(self,pn=None):
"""next page"""
ret=""
try:
pn=str(int(pn)+1)
except:
pn=str(2)
self.REQUEST.form['pn']=pn
for param in self.REQUEST.form.keys():
ret+=param+"="+str(self.REQUEST.form[param])+"&"
self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+'?'+ret)
def generateDivs(self):
"""generate divs"""
pt=PageTemplateFile('Products/zogiLib/zpt/zogilib_divs').__of__(self)
return pt()
#divFileName=os.path.join(package_home(globals()),'zpt/zogilib_divs.zpt')
#return open(divFileName).read()
def manage_addZogiLibForm(self):
"""interface for adding zogilib"""
pt=PageTemplateFile('Products/zogiLib/zpt/addZogiLibForm').__of__(self)
return pt()
def manage_addZogiLib(self,id,title,digilibBaseUrl, localFileBase,version="book",RESPONSE=None):
"""add dgilib"""
newObj=zogiLib(id,title,digilibBaseUrl, localFileBase, version)
self.Destination()._setObject(id,newObj)
if RESPONSE is not None:
RESPONSE.redirect('manage_main')
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>