source: documentViewer/MpdlXmlTextServer.py @ 471:415a7026eeda

elementtree
Last change on this file since 471:415a7026eeda was 471:415a7026eeda, checked in by casties, 13 years ago

split viewMode in viewMode and viewType

File size: 24.2 KB
Line 
1from OFS.SimpleItem import SimpleItem
2from Products.PageTemplates.PageTemplateFile import PageTemplateFile
3
4from Ft.Xml import EMPTY_NAMESPACE, Parse
5from Ft.Xml.Domlette import NonvalidatingReader
6import Ft.Xml.Domlette
7import cStringIO
8
9import xml.etree.ElementTree as ET
10
11import re
12import logging
13import urllib
14
15from SrvTxtUtils import getInt, getText, getHttpData
16
17def serialize(node):
18    """returns a string containing an XML snippet of node"""
19    s = ET.tostring(node, 'UTF-8')
20    # snip off XML declaration
21    if s.startswith('<?xml'):
22        i = s.find('?>')
23        return s[i+3:]
24
25    return s
26
27
28def getTextFromNode(node):
29    """get the cdata content of a node"""
30    if node is None:
31        return ""
32    # ET:
33#    text = node.text or ""
34#    for e in node:
35#        text += gettext(e)
36#        if e.tail:
37#            text += e.tail
38
39    # 4Suite:
40    nodelist=node.childNodes
41    text = ""
42    for n in nodelist:
43        if n.nodeType == node.TEXT_NODE:
44           text = text + n.data
45   
46    return text
47
48def serializeNode(node, encoding="utf-8"):
49    """returns a string containing node as XML"""
50    #s = ET.tostring(node)
51   
52    # 4Suite:
53    stream = cStringIO.StringIO()
54    Ft.Xml.Domlette.Print(node, stream=stream, encoding=encoding)
55    s = stream.getvalue()
56    stream.close()
57
58    return s
59
60
61class MpdlXmlTextServer(SimpleItem):
62    """TextServer implementation for MPDL-XML eXist server"""
63    meta_type="MPDL-XML TextServer"
64
65    manage_options=(
66        {'label':'Config','action':'manage_changeMpdlXmlTextServerForm'},
67       )+SimpleItem.manage_options
68   
69    manage_changeMpdlXmlTextServerForm = PageTemplateFile("zpt/manage_changeMpdlXmlTextServer", globals())
70       
71    def __init__(self,id,title="",serverUrl="http://mpdl-text.mpiwg-berlin.mpg.de/mpdl/interface/", serverName=None, timeout=40):
72        """constructor"""
73        self.id=id
74        self.title=title
75        self.timeout = timeout
76        if serverName is None:
77            self.serverUrl = serverUrl
78        else:
79            self.serverUrl = "http://%s/mpdl/interface/"%serverName
80       
81    def getHttpData(self, url, data=None):
82        """returns result from url+data HTTP request"""
83        return getHttpData(url,data,timeout=self.timeout)
84   
85    def getServerData(self, method, data=None):
86        """returns result from text server for method+data"""
87        url = self.serverUrl+method
88        return getHttpData(url,data,timeout=self.timeout)
89
90    # WTF: what does this really do? can it be integrated in getPage?
91    def getSearch(self, pageinfo=None,  docinfo=None):
92        """get search list"""
93        logging.debug("getSearch()")
94        docpath = docinfo['textURLPath'] 
95        url = docinfo['url']
96        pagesize = pageinfo['queryPageSize']
97        pn = pageinfo.get('searchPN',1)
98        sn = pageinfo['sn']
99        highlightQuery = pageinfo['highlightQuery']
100        query =pageinfo['query']
101        queryType =pageinfo['queryType']
102        viewMode=  pageinfo['viewMode']
103        tocMode = pageinfo['tocMode']
104        characterNormalization = pageinfo['characterNormalization']
105        #optionToggle = pageinfo['optionToggle']
106        tocPN = pageinfo['tocPN']
107        selfurl = self.absolute_url()
108        data = self.getServerData("doc-query.xql","document=%s&mode=%s&queryType=%s&query=%s&queryResultPageSize=%s&queryResultPN=%s&sn=%s&viewMode=%s&characterNormalization=%s&highlightQuery=%s"%(docpath, 'text', queryType, urllib.quote(query), pagesize, pn, sn, viewMode,characterNormalization, urllib.quote(highlightQuery)))
109        pagexml = data.replace('?document=%s'%str(docpath),'?url=%s'%url)
110        pagedom = Parse(pagexml)
111       
112        """
113        pagedivs = pagedom.xpath("//div[@class='queryResultHits']")
114        if (pagedivs == pagedom.xpath("//div[@class='queryResultHits']")):
115            if len(pagedivs)>0:
116                docinfo['queryResultHits'] = int(getTextFromNode(pagedivs[0]))
117                s = getTextFromNode(pagedivs[0])
118                s1 = int(s)/10+1
119                try:
120                    docinfo['queryResultHits'] = int(s1)
121                    logging.debug("SEARCH ENTRIES: %s"%(s1))
122                except:
123                    docinfo['queryResultHits'] = 0
124        """
125        if (queryType=="fulltext")or(queryType=="xpath")or(queryType=="xquery")or(queryType=="fulltextMorphLemma"):   
126            pagedivs = pagedom.xpath("//div[@class='queryResultPage']")
127            if len(pagedivs)>0:
128                pagenode=pagedivs[0]
129                links=pagenode.xpath("//a")
130                for l in links:
131                    hrefNode = l.getAttributeNodeNS(None, u"href")
132                    if hrefNode:
133                        href = hrefNode.nodeValue
134                        if href.startswith('page-fragment.xql'):
135                            selfurl = self.absolute_url()           
136                            pagexml=href.replace('mode=text','mode=texttool&viewMode=%s&queryType=%s&query=%s&queryResultPageSize=%s&queryResultPN=%s&tocMode=%s&searchPN=%s&tocPN=%s&characterNormalization=%s'%(viewMode,queryType,urllib.quote(query),pagesize,pn,tocMode,pn,tocPN, characterNormalization))
137                            hrefNode.nodeValue = pagexml.replace('page-fragment.xql','%s'%selfurl)                                           
138                #logging.debug("PUREXML :%s"%(serializeNode(pagenode)))
139                return serializeNode(pagenode)       
140        if (queryType=="fulltextMorph"):
141            pagedivs = pagedom.xpath("//div[@class='queryResult']")
142            if len(pagedivs)>0:
143                pagenode=pagedivs[0]
144                links=pagenode.xpath("//a")
145                for l in links:
146                    hrefNode = l.getAttributeNodeNS(None, u"href")
147                    if hrefNode:
148                        href = hrefNode.nodeValue
149                        if href.startswith('page-fragment.xql'):
150                            selfurl = self.absolute_url()       
151                            pagexml=href.replace('mode=text','mode=texttool&viewMode=%s&queryType=%s&query=%s&queryResultPageSize=%s&queryResultPN=%s&tocMode=%s&searchPN=%s&tocPN=%s&characterNormalization=%s'%(viewMode,queryType,urllib.quote(query),pagesize,pn,tocMode,pn,tocPN,characterNormalization))
152                            hrefNode.nodeValue = pagexml.replace('page-fragment.xql','%s'%selfurl) 
153                        if href.startswith('../lt/lemma.xql'):
154                            hrefNode.nodeValue = href.replace('../lt/lemma.xql','%s/template/head_main_query'%(selfurl))       
155                            l.setAttributeNS(None, 'target', '_blank')
156                            l.setAttributeNS(None, 'onClick',"popupWin = window.open(this.href, 'contacts', 'location,width=500,height=600,top=180, left=400, scrollbars=1'); return false;")
157                            l.setAttributeNS(None, 'onDblclick', 'popupWin.focus();') 
158                pagedivs = pagedom.xpath("//div[@class='queryResultMorphExpansion']")               
159                return serializeNode(pagenode)       
160        if (queryType=="ftIndex")or(queryType=="ftIndexMorph"):
161            pagedivs= pagedom.xpath("//div[@class='queryResultPage']")
162            if len(pagedivs)>0:
163                pagenode=pagedivs[0]
164                links=pagenode.xpath("//a")
165                for l in links:
166                    hrefNode = l.getAttributeNodeNS(None, u"href")
167                    if hrefNode:
168                        href = hrefNode.nodeValue
169                        hrefNode.nodeValue=href.replace('mode=text','mode=texttool&viewMode=%s&tocMode=%s&tocPN=%s&pn=%s&characterNormalization=%s'%(viewMode,tocMode,tocPN,pn,characterNormalization))             
170                        if href.startswith('../lt/lex.xql'):
171                            hrefNode.nodeValue = href.replace('../lt/lex.xql','%s/template/head_main_lex'%selfurl)         
172                            l.setAttributeNS(None, 'target', '_blank')
173                            l.setAttributeNS(None, 'onClick',"popupWin = window.open(this.href, 'contacts', 'location,width=500,height=600,top=180, left=400, scrollbars=1'); return false;")
174                            l.setAttributeNS(None, 'onDblclick', 'popupWin.focus();')
175                        if href.startswith('../lt/lemma.xql'):
176                            hrefNode.nodeValue = href.replace('../lt/lemma.xql','%s/template/head_main_lemma'%(selfurl))       
177                            l.setAttributeNS(None, 'target', '_blank')
178                            l.setAttributeNS(None, 'onClick',"popupWin = window.open(this.href, 'contacts', 'location,width=500,height=600,top=180, left=400, scrollbars=1'); return false;")
179                            l.setAttributeNS(None, 'onDblclick', 'popupWin.focus();')
180                return serializeNode(pagenode)     
181        return "no text here"   
182           
183    def getGisPlaces(self, docinfo=None, pageinfo=None):
184        """ Show all Gis Places of whole Page"""
185        xpath='//place'
186        docpath = docinfo.get('textURLPath',None)
187        if not docpath:
188            return None
189
190        url = docinfo['url']
191        selfurl = self.absolute_url()
192        pn = pageinfo['current']
193        hrefList=[]
194        myList= ""
195        text=self.getServerData("xpath.xql", "document=%s&xpath=%s&pn=%s"%(docinfo['textURLPath'],xpath,pn))
196        dom = ET.fromstring(text)
197        result = dom.findall(".//result/resultPage/place")
198        for l in result:
199            href = l.get("id")
200            hrefList.append(href)
201            # WTF: what does this do?
202            myList = ",".join(hrefList)
203        #logging.debug("getGisPlaces :%s"%(myList))                             
204        return myList
205   
206    def getAllGisPlaces (self, docinfo=None, pageinfo=None):
207        """Show all Gis Places of whole Book """
208        xpath ='//echo:place'
209        docpath =docinfo['textURLPath']
210        url = docinfo['url']
211        selfurl =self.absolute_url()
212        pn =pageinfo['current']
213        hrefList=[]
214        myList=""
215        text=self.getServerData("xpath.xql", "document=%s&xpath=%s"%(docinfo['textURLPath'],xpath))
216        dom = ET.fromstring(text)
217        result = dom.findall(".//result/resultPage/place")
218       
219        for l in result:
220            href = l.get("id")
221            hrefList.append(href)
222            # WTF: what does this do?
223            myList = ",".join(hrefList)
224            #logging.debug("getALLGisPlaces :%s"%(myList))
225        return myList
226         
227    def processPageInfo(self, dom, docinfo, pageinfo):
228        """processes page info divs from dom and stores in docinfo and pageinfo"""
229        # assume first second level div is pageMeta
230        alldivs = dom.find("div")
231        for div in alldivs:
232            dc = div.get('class')
233           
234            # pageNumberOrig 
235            if dc == 'pageNumberOrig':
236                pageinfo['pageNumberOrig'] = div.text
237               
238            # pageNumberOrigNorm
239            elif dc == 'pageNumberOrigNorm':
240                pageinfo['pageNumberOrigNorm'] = div.text
241               
242            # pageNumberOrigNorm
243            elif dc == 'countFigureEntries':
244                docinfo['numFigureEntries'] = getInt(div.text)
245               
246            # pageNumberOrigNorm
247            elif dc == 'countTocEntries':
248                # WTF: s1 = int(s)/30+1
249                docinfo['numTocEntries'] = getInt(div.text)
250               
251            # pageHeaderTitle
252            elif dc == 'pageHeaderTitle':
253                docinfo['pageHeaderTitle'] = div.text
254               
255            # numTextPages
256            elif dc == 'countPages':
257                np = getInt(div.text)                   
258                if np > 0:
259                    docinfo['numTextPages'] = np
260                    if docinfo.get('numPages', 0) == 0:
261                        # seems to be text-only - update page count
262                        docinfo['numPages'] = np
263                        pageinfo['end'] = min(pageinfo['end'], np)
264                        pageinfo['numgroups'] = int(np / pageinfo['groupsize'])
265                        if np % pageinfo['groupsize'] > 0:
266                            pageinfo['numgroups'] += 1
267                           
268        return
269         
270           
271    def getTextPage(self, mode="text", pn=1, docinfo=None, pageinfo=None):
272        """returns single page from fulltext"""
273        logging.debug("getTextPage mode=%s, pn=%s"%(mode,pn))
274        # check for cached text -- but this shouldn't be called twice
275        if pageinfo.has_key('textPage'):
276            logging.debug("getTextPage: using cached text")
277            return pageinfo['textPage']
278       
279        docpath = docinfo['textURLPath']
280        # just checking
281        if pageinfo['current'] != pn:
282            logging.warning("getTextPage: current!=pn!")
283           
284        # stuff for constructing full urls
285        url = docinfo['url']
286        urlmode = docinfo['mode']
287        sn = pageinfo.get('sn', None)
288        highlightQuery = pageinfo.get('highlightQuery', None)
289        tocMode = pageinfo.get('tocMode', None)
290        tocPN = pageinfo.get('tocPN',None)
291        characterNormalization = pageinfo.get('characterNormalization', None)
292        selfurl = docinfo['viewerUrl']   
293       
294        if mode == "dict":
295            # text_dict is called textPollux in the backend
296            textmode = "textPollux"
297        elif not mode:
298            # default is text
299            textmode = "text"
300        else:
301            textmode = mode
302       
303        textParam = "document=%s&mode=%s&pn=%s&characterNormalization=%s"%(docpath,textmode,pn,characterNormalization)
304        if highlightQuery:
305            textParam +="&highlightQuery=%s&sn=%s"%(urllib.quote(highlightQuery),sn)           
306       
307        # fetch the page
308        pagexml = self.getServerData("page-fragment.xql",textParam)
309        dom = ET.fromstring(pagexml)
310        # extract additional info
311        self.processPageInfo(dom, docinfo, pageinfo)
312        # page content is in <div class="pageContent">
313        pagediv = None
314        # ElementTree 1.2 in Python 2.6 can't do div[@class='pageContent']
315        # so we look at the second level divs
316        alldivs = dom.findall("div")
317        for div in alldivs:
318            dc = div.get('class')
319            # page content div
320            if dc == 'pageContent':
321                pagediv = div
322                break
323       
324        # plain text mode
325        if mode == "text":
326            if pagediv:
327                links = pagediv.findall(".//a")
328                for l in links:
329                    href = l.get('href')
330                    if href and href.startswith('#note-'):
331                        href = href.replace('#note-',"?mode=%s&url=%s&viewMode=text&tocMode=%s&tocPN=%s&pn=%s#note-"%(urlmode,url,tocMode,tocPN,pn))
332                        l.set('href', href)
333
334                return serialize(pagediv)
335           
336        # text-with-links mode
337        elif mode == "text_dict":
338            if pagediv:
339                # check all a-tags
340                links = pagediv.findall(".//a")
341                for l in links:
342                    href = l.get('href')
343                   
344                    if href:
345                        # is link with href
346                        if href.startswith('http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/interface/lt/wordInfo.xql'):
347                            # is pollux link
348                            selfurl = self.absolute_url()
349                            # change href
350                            l.set('href', href.replace('http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/interface/lt/wordInfo.xql','%s/head_main_voc'%selfurl))
351                            # add target
352                            l.set('target', '_blank')
353                                                         
354                        if href.startswith('http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/lt/lemma.xql'):   
355                            selfurl = self.absolute_url()
356                            l.set('href', href.replace('http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/lt/lemma.xql','%s/head_main_lemma'%selfurl))
357                            l.set('target', '_blank')
358                            l.set('onclick',"popupWin = window.open(this.href, 'InfoWindow', 'menubar=no, location,width=500,height=600,top=180, left=700, toolbar=no, scrollbars=1'); return false;")
359                            l.set('ondblclick', 'popupWin.focus();')   
360                   
361                        if href.startswith('#note-'):
362                            l.set('href', href.replace('#note-',"?mode=%s&url=%s&viewMode=text_dict&tocMode=%s&tocPN=%s&pn=%s#note-"%(urlmode,url,tocMode,tocPN,pn)))
363                             
364                return serialize(pagediv)
365           
366        # xml mode
367        elif mode == "xml":
368            if pagediv:
369                return serialize(pagediv)
370           
371        # pureXml mode
372        elif mode == "pureXml":
373            if pagediv:
374                return serialize(pagediv)
375                 
376        # gis mode
377        elif mode == "gis":
378            name = docinfo['name']
379            if pagediv:
380                # check all a-tags
381                links = pagediv.findall(".//a")
382                for l in links:
383                    href = l.get('href')
384                    if href:
385                        if href.startswith('http://chinagis.mpiwg-berlin.mpg.de'):
386                            l.set('href', href.replace('chinagis_REST/REST/db/chgis/mpdl','chinagis/REST/db/mpdl/%s'%name))
387                            l.set('target', '_blank') 
388                           
389                return serialize(pagediv)
390                   
391        return "no text here"
392   
393    # WTF: is this needed?
394    def getOrigPages(self, docinfo=None, pageinfo=None):
395        logging.debug("CALLED: getOrigPages!")
396        if not pageinfo.has_key('pageNumberOrig'):
397            logging.warning("getOrigPages: not in pageinfo!")
398            return None
399       
400        return pageinfo['pageNumberOrig']
401   
402    # WTF: is this needed?
403    def getOrigPagesNorm(self, docinfo=None, pageinfo=None):
404        logging.debug("CALLED: getOrigPagesNorm!")
405        if not pageinfo.has_key('pageNumberOrigNorm'):
406            logging.warning("getOrigPagesNorm: not in pageinfo!")
407            return None
408       
409        return pageinfo['pageNumberOrigNorm']
410               
411    # TODO: should be getWordInfo
412    def getTranslate(self, word=None, language=None):
413        """translate into another languages"""
414        data = self.getServerData("lt/wordInfo.xql","language="+str(language)+"&word="+urllib.quote(word)+"&output=html")
415        return data
416   
417    # WTF: what does this do?
418    def getLemma(self, lemma=None, language=None):
419        """simular words lemma """
420        data = self.getServerData("lt/lemma.xql","language="+str(language)+"&lemma="+urllib.quote(lemma)+"&output=html")
421        return data
422   
423    # WTF: what does this do?
424    def getLemmaQuery(self, query=None, language=None):
425        """simular words lemma """
426        data = self.getServerData("lt/lemma.xql","language="+str(language)+"&query="+urllib.quote(query)+"&output=html")
427        return data
428   
429    # WTF: what does this do?
430    def getLex(self, query=None, language=None):
431        #simular words lemma
432        data = self.getServerData("lt/lex.xql","document=&language="+str(language)+"&query="+urllib.quote(query))
433        return data
434
435    # WTF: what does this do?
436    def getQuery (self,  docinfo=None, pageinfo=None, query=None, queryType=None, pn=1):
437         #number of
438         docpath = docinfo['textURLPath'] 
439         pagesize = pageinfo['queryPageSize']
440         pn = pageinfo['searchPN']
441         query =pageinfo['query']
442         queryType =pageinfo['queryType']
443         tocSearch = 0
444         tocDiv = None
445         
446         pagexml = self.getServerData("doc-query.xql","document=%s&mode=%s&queryType=%s&query=%s&queryResultPageSize=%s&queryResultPN=%s"%(docpath, 'text', queryType, urllib.quote(query), pagesize, pn))
447         pagedom = Parse(pagexml)
448         numdivs = pagedom.xpath("//div[@class='queryResultHits']")
449         tocSearch = int(getTextFromNode(numdivs[0]))
450         tc=int((tocSearch/10)+1)
451         return tc
452   
453    def getToc(self, mode="text", docinfo=None):
454        """loads table of contents and stores XML in docinfo"""
455        logging.debug("getToc mode=%s"%mode)
456        if mode == "none":
457            return docinfo
458             
459        if 'tocSize_%s'%mode in docinfo:
460            # cached toc
461            return docinfo
462       
463        docpath = docinfo['textURLPath']
464        # we need to set a result set size
465        pagesize = 1000
466        pn = 1
467        if mode == "text":
468            queryType = "toc"
469        else:
470            queryType = mode
471        # number of entries in toc
472        tocSize = 0
473        tocDiv = None
474        # fetch full toc
475        pagexml = self.getServerData("doc-query.xql","document=%s&queryType=%s&queryResultPageSize=%s&queryResultPN=%s"%(docpath,queryType, pagesize, pn))
476        dom = ET.fromstring(pagexml)
477        # page content is in <div class="queryResultPage">
478        pagediv = None
479        # ElementTree 1.2 in Python 2.6 can't do div[@class='queryResultPage']
480        alldivs = dom.findall("div")
481        for div in alldivs:
482            dc = div.get('class')
483            # page content div
484            if dc == 'queryResultPage':
485                pagediv = div
486               
487            elif dc == 'queryResultHits':
488                docinfo['tocSize_%s'%mode] = getInt(div.text)
489
490        if pagediv:
491            # store XML in docinfo
492            docinfo['tocXML_%s'%mode] = ET.tostring(pagediv, 'UTF-8')
493
494        return docinfo
495   
496    def getTocPage(self, mode="text", pn=1, pageinfo=None, docinfo=None):
497        """returns single page from the table of contents"""
498        logging.debug("getTocPage mode=%s, pn=%s"%(mode,pn))
499        if mode == "text":
500            queryType = "toc"
501        else:
502            queryType = mode
503           
504        # check for cached TOC
505        if not docinfo.has_key('tocXML_%s'%mode):
506            self.getToc(mode=mode, docinfo=docinfo)
507           
508        tocxml = docinfo.get('tocXML_%s'%mode, None)
509        if not tocxml:
510            logging.error("getTocPage: unable to find tocXML")
511            return "No ToC"
512       
513        pagesize = int(pageinfo['tocPageSize'])
514        url = docinfo['url']
515        urlmode = docinfo['mode']
516        selfurl = docinfo['viewerUrl']
517        viewMode=  pageinfo['viewMode']
518        tocMode = pageinfo['tocMode']
519        tocPN = int(pageinfo['tocPN'])
520        pn = tocPN
521
522        fulltoc = ET.fromstring(tocxml)
523       
524        if fulltoc:
525            # paginate
526            start = (pn - 1) * pagesize * 2
527            len = pagesize * 2
528            del fulltoc[:start]
529            del fulltoc[len:]
530            tocdivs = fulltoc
531           
532            # check all a-tags
533            links = tocdivs.findall(".//a")
534            for l in links:
535                href = l.get('href')
536                if href:
537                    # take pn from href
538                    m = re.match(r'page-fragment\.xql.*pn=(\d+)', href)
539                    if m is not None:
540                        # and create new url
541                        l.set('href', '%s?mode=%s&url=%s&viewMode=%s&pn=%s&tocMode=%s&tocPN=%s'%(selfurl, urlmode, url, viewMode, m.group(1), tocMode, tocPN))
542                    else:
543                        logging.warning("getTocPage: Problem with link=%s"%href)
544                       
545            return serialize(tocdivs)
546   
547   
548    def manage_changeMpdlXmlTextServer(self,title="",serverUrl="http://mpdl-text.mpiwg-berlin.mpg.de/mpdl/interface/",timeout=40,RESPONSE=None):
549        """change settings"""
550        self.title=title
551        self.timeout = timeout
552        self.serverUrl = serverUrl
553        if RESPONSE is not None:
554            RESPONSE.redirect('manage_main')
555       
556# management methods
557def manage_addMpdlXmlTextServerForm(self):
558    """Form for adding"""
559    pt = PageTemplateFile("zpt/manage_addMpdlXmlTextServer", globals()).__of__(self)
560    return pt()
561
562def manage_addMpdlXmlTextServer(self,id,title="",serverUrl="http://mpdl-text.mpiwg-berlin.mpg.de/mpdl/interface/",timeout=40,RESPONSE=None):
563#def manage_addMpdlXmlTextServer(self,id,title="",serverUrl="http://mpdl-text.mpiwg-berlin.mpg.de:30030/mpdl/interface/",timeout=40,RESPONSE=None):   
564    """add zogiimage"""
565    newObj = MpdlXmlTextServer(id,title,serverUrl,timeout)
566    self.Destination()._setObject(id, newObj)
567    if RESPONSE is not None:
568        RESPONSE.redirect('manage_main')
569       
570       
Note: See TracBrowser for help on using the repository browser.