Mercurial > hg > documentViewer
annotate MpdlXmlTextServer.py @ 517:aaacdf551f6f
remove global info from processPageInfo.
author | casties |
---|---|
date | Mon, 05 Mar 2012 19:11:59 +0100 |
parents | 7d7b639d7be7 |
children | 91051b36b9cc |
rev | line source |
---|---|
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
1 from OFS.SimpleItem import SimpleItem |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
2 from Products.PageTemplates.PageTemplateFile import PageTemplateFile |
455 | 3 |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
4 import xml.etree.ElementTree as ET |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
5 |
455 | 6 import re |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
7 import logging |
134 | 8 import urllib |
511 | 9 import urlparse |
506 | 10 import base64 |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
11 |
458 | 12 from SrvTxtUtils import getInt, getText, getHttpData |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
13 |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
14 def serialize(node): |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
15 """returns a string containing an XML snippet of node""" |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
16 s = ET.tostring(node, 'UTF-8') |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
17 # snip off XML declaration |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
18 if s.startswith('<?xml'): |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
19 i = s.find('?>') |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
20 return s[i+3:] |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
21 |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
22 return s |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
23 |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
24 |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
25 class MpdlXmlTextServer(SimpleItem): |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
26 """TextServer implementation for MPDL-XML eXist server""" |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
27 meta_type="MPDL-XML TextServer" |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
28 |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
29 manage_options=( |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
30 {'label':'Config','action':'manage_changeMpdlXmlTextServerForm'}, |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
31 )+SimpleItem.manage_options |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
32 |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
33 manage_changeMpdlXmlTextServerForm = PageTemplateFile("zpt/manage_changeMpdlXmlTextServer", globals()) |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
34 |
455 | 35 def __init__(self,id,title="",serverUrl="http://mpdl-text.mpiwg-berlin.mpg.de/mpdl/interface/", serverName=None, timeout=40): |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
36 """constructor""" |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
37 self.id=id |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
38 self.title=title |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
39 self.timeout = timeout |
132 | 40 if serverName is None: |
41 self.serverUrl = serverUrl | |
42 else: | |
43 self.serverUrl = "http://%s/mpdl/interface/"%serverName | |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
44 |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
45 def getHttpData(self, url, data=None): |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
46 """returns result from url+data HTTP request""" |
458 | 47 return getHttpData(url,data,timeout=self.timeout) |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
48 |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
49 def getServerData(self, method, data=None): |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
50 """returns result from text server for method+data""" |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
51 url = self.serverUrl+method |
458 | 52 return getHttpData(url,data,timeout=self.timeout) |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
53 |
506 | 54 |
55 def getPlacesOnPage(self, docinfo=None, pn=None): | |
56 """Returns list of GIS places of page pn""" | |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
57 docpath = docinfo.get('textURLPath',None) |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
58 if not docpath: |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
59 return None |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
60 |
506 | 61 places=[] |
62 text=self.getServerData("xpath.xql", "document=%s&xpath=//place&pn=%s"%(docpath,pn)) | |
455 | 63 dom = ET.fromstring(text) |
506 | 64 result = dom.findall(".//resultPage/place") |
236 | 65 for l in result: |
506 | 66 id = l.get("id") |
67 name = l.text | |
68 place = {'id': id, 'name': name} | |
69 places.append(place) | |
70 | |
71 return places | |
307 | 72 |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
73 |
517 | 74 def getTextInfo(self, mode='', docinfo=None): |
516 | 75 """reads document info, including page concordance, from text server""" |
76 logging.debug("getDocInfo") | |
517 | 77 #TODO: check cached info |
516 | 78 docpath = docinfo.get('textURLPath', None) |
79 if docpath is None: | |
80 logging.error("getTextInfo: no textURLPath!") | |
81 return docinfo | |
517 | 82 |
516 | 83 # we need to set a result set size |
84 pagesize = 10000 | |
85 pn = 1 | |
86 # fetch docinfo | |
517 | 87 pagexml = self.getServerData("doc-info.xql","document=%s&info=%s&pageSize=%s&pn=%s"%(docpath,mode,pagesize,pn)) |
516 | 88 dom = ET.fromstring(pagexml) |
89 # all info in tag <document> | |
90 doc = dom.find("document") | |
91 if doc is None: | |
92 logging.error("getTextInfo: unable to find document-tag!") | |
93 else: | |
94 # go through all child elements | |
95 for tag in doc: | |
96 name = tag.tag | |
97 # numTextPages | |
98 if name == 'countPages': | |
99 np = getInt(tag.text) | |
100 if np > 0: | |
101 docinfo['numTextPages'] = np | |
102 | |
103 # numFigureEntries | |
104 elif name == 'countFigureEntries': | |
105 docinfo['numFigureEntries'] = getInt(tag.text) | |
106 | |
107 # numTocEntries | |
108 elif name == 'countTocEntries': | |
109 # WTF: s1 = int(s)/30+1 | |
110 docinfo['numTocEntries'] = getInt(tag.text) | |
111 | |
112 # numPlaces | |
113 elif name == 'countPlaces': | |
114 docinfo['numPlaces'] = getInt(tag.text) | |
115 | |
116 # pageNumbers | |
117 elif name == 'pageNumbers': | |
118 # contains tags with page numbers | |
119 # <pn><n>4</n><no>4</no><non/></pn> | |
120 # n=scan number, no=original page no, non=normalized original page no | |
121 # pageNumbers is a dict indexed by scan number | |
122 pages = {} | |
123 for pn in tag: | |
124 page = {} | |
125 n = 0 | |
126 for p in pn: | |
127 if p.tag == 'n': | |
128 n = getInt(p.text) | |
129 page['n'] = n | |
130 elif p.tag == 'no': | |
131 page['no'] = p.text | |
132 elif p.tag == 'non': | |
133 page['non'] = p.text | |
134 | |
135 if n > 0: | |
136 pages[n] = page | |
137 | |
138 docinfo['pageNumbers'] = pages | |
517 | 139 #logging.debug("got pageNumbers=%s"%repr(pages)) |
516 | 140 |
517 | 141 # toc |
142 elif name == 'toc': | |
143 # contains tags with table of contents | |
144 # TODO: implement | |
145 pass | |
146 | |
516 | 147 return docinfo |
148 | |
149 | |
455 | 150 def processPageInfo(self, dom, docinfo, pageinfo): |
151 """processes page info divs from dom and stores in docinfo and pageinfo""" | |
469 | 152 # assume first second level div is pageMeta |
153 alldivs = dom.find("div") | |
473 | 154 |
155 if alldivs is None or alldivs.get('class', '') != 'pageMeta': | |
156 logging.error("processPageInfo: pageMeta div not found!") | |
157 return | |
158 | |
455 | 159 for div in alldivs: |
160 dc = div.get('class') | |
161 | |
162 # pageNumberOrig | |
469 | 163 if dc == 'pageNumberOrig': |
455 | 164 pageinfo['pageNumberOrig'] = div.text |
165 | |
166 # pageNumberOrigNorm | |
167 elif dc == 'pageNumberOrigNorm': | |
168 pageinfo['pageNumberOrigNorm'] = div.text | |
169 | |
474 | 170 # pageHeaderTitle |
171 elif dc == 'pageHeaderTitle': | |
172 pageinfo['pageHeaderTitle'] = div.text | |
517 | 173 |
473 | 174 #logging.debug("processPageInfo: pageinfo=%s"%repr(pageinfo)) |
455 | 175 return |
176 | |
388 | 177 |
471 | 178 def getTextPage(self, mode="text", pn=1, docinfo=None, pageinfo=None): |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
179 """returns single page from fulltext""" |
508 | 180 |
455 | 181 logging.debug("getTextPage mode=%s, pn=%s"%(mode,pn)) |
478 | 182 # check for cached text -- but ideally this shouldn't be called twice |
455 | 183 if pageinfo.has_key('textPage'): |
184 logging.debug("getTextPage: using cached text") | |
185 return pageinfo['textPage'] | |
186 | |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
187 docpath = docinfo['textURLPath'] |
455 | 188 # just checking |
189 if pageinfo['current'] != pn: | |
190 logging.warning("getTextPage: current!=pn!") | |
191 | |
192 # stuff for constructing full urls | |
478 | 193 selfurl = docinfo['viewerUrl'] |
511 | 194 textParams = {'document': docpath, |
195 'pn': pn} | |
196 if 'characterNormalization' in pageinfo: | |
197 textParams['characterNormalization'] = pageinfo['characterNormalization'] | |
455 | 198 |
508 | 199 if not mode: |
200 # default is dict | |
201 mode = 'text' | |
202 | |
203 modes = mode.split(',') | |
204 # check for multiple layers | |
205 if len(modes) > 1: | |
206 logging.debug("getTextPage: more than one mode=%s"%mode) | |
207 | |
208 # search mode | |
209 if 'search' in modes: | |
210 # add highlighting | |
211 highlightQuery = pageinfo.get('highlightQuery', None) | |
511 | 212 if highlightQuery: |
213 textParams['highlightQuery'] = highlightQuery | |
214 textParams['highlightElement'] = pageinfo.get('highlightElement', '') | |
215 textParams['highlightElementPos'] = pageinfo.get('highlightElementPos', '') | |
508 | 216 |
511 | 217 # ignore mode in the following |
508 | 218 modes.remove('search') |
219 | |
220 # other modes don't combine | |
221 if 'dict' in modes: | |
473 | 222 # dict is called textPollux in the backend |
508 | 223 textmode = 'textPollux' |
224 elif len(modes) == 0: | |
225 # text is default mode | |
226 textmode = 'text' | |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
227 else: |
508 | 228 # just take first mode |
229 textmode = modes[0] | |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
230 |
511 | 231 textParams['mode'] = textmode |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
232 |
455 | 233 # fetch the page |
511 | 234 pagexml = self.getServerData("page-fragment.xql",urllib.urlencode(textParams)) |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
235 dom = ET.fromstring(pagexml) |
455 | 236 # extract additional info |
237 self.processPageInfo(dom, docinfo, pageinfo) | |
238 # page content is in <div class="pageContent"> | |
239 pagediv = None | |
240 # ElementTree 1.2 in Python 2.6 can't do div[@class='pageContent'] | |
469 | 241 # so we look at the second level divs |
242 alldivs = dom.findall("div") | |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
243 for div in alldivs: |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
244 dc = div.get('class') |
455 | 245 # page content div |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
246 if dc == 'pageContent': |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
247 pagediv = div |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
248 break |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
249 |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
250 # plain text mode |
508 | 251 if textmode == "text": |
478 | 252 # get full url assuming documentViewer is parent |
253 selfurl = self.getLink() | |
473 | 254 if pagediv is not None: |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
255 links = pagediv.findall(".//a") |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
256 for l in links: |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
257 href = l.get('href') |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
258 if href and href.startswith('#note-'): |
478 | 259 href = href.replace('#note-',"%s#note-"%selfurl) |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
260 l.set('href', href) |
455 | 261 |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
262 return serialize(pagediv) |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
263 |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
264 # text-with-links mode |
508 | 265 elif textmode == "textPollux": |
473 | 266 if pagediv is not None: |
478 | 267 viewerurl = docinfo['viewerUrl'] |
268 selfurl = self.getLink() | |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
269 # check all a-tags |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
270 links = pagediv.findall(".//a") |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
271 for l in links: |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
272 href = l.get('href') |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
273 |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
274 if href: |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
275 # is link with href |
511 | 276 linkurl = urlparse.urlparse(href) |
277 #logging.debug("getTextPage: linkurl=%s"%repr(linkurl)) | |
278 if linkurl.path.endswith('GetDictionaryEntries'): | |
279 #TODO: replace wordInfo page | |
478 | 280 # is dictionary link - change href (keeping parameters) |
511 | 281 #l.set('href', href.replace('http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/interface/lt/wordInfo.xql','%s/template/viewer_wordinfo'%viewerurl)) |
478 | 282 # add target to open new page |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
283 l.set('target', '_blank') |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
284 |
478 | 285 # TODO: is this needed? |
511 | 286 # if href.startswith('http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/lt/lemma.xql'): |
287 # selfurl = self.absolute_url() | |
288 # l.set('href', href.replace('http://mpdl-proto.mpiwg-berlin.mpg.de/mpdl/lt/lemma.xql','%s/head_main_lemma'%selfurl)) | |
289 # l.set('target', '_blank') | |
290 # 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;") | |
291 # l.set('ondblclick', 'popupWin.focus();') | |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
292 |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
293 if href.startswith('#note-'): |
478 | 294 # note link |
295 l.set('href', href.replace('#note-',"%s#note-"%selfurl)) | |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
296 |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
297 return serialize(pagediv) |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
298 |
455 | 299 # xml mode |
508 | 300 elif textmode == "xml": |
473 | 301 if pagediv is not None: |
455 | 302 return serialize(pagediv) |
303 | |
304 # pureXml mode | |
508 | 305 elif textmode == "pureXml": |
473 | 306 if pagediv is not None: |
455 | 307 return serialize(pagediv) |
308 | |
309 # gis mode | |
508 | 310 elif textmode == "gis": |
473 | 311 if pagediv is not None: |
455 | 312 # check all a-tags |
313 links = pagediv.findall(".//a") | |
506 | 314 # add our URL as backlink |
315 selfurl = self.getLink() | |
316 doc = base64.b64encode(selfurl) | |
455 | 317 for l in links: |
318 href = l.get('href') | |
319 if href: | |
506 | 320 if href.startswith('http://mappit.mpiwg-berlin.mpg.de'): |
321 l.set('href', re.sub(r'doc=[\w+/=]+', 'doc=%s'%doc, href)) | |
322 l.set('target', '_blank') | |
455 | 323 |
324 return serialize(pagediv) | |
325 | |
501 | 326 return None |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
327 |
455 | 328 |
509
9d05befdd462
try to get characterNormalization in search result working.
casties
parents:
508
diff
changeset
|
329 def getSearchResults(self, mode, query=None, pageinfo=None, docinfo=None): |
508 | 330 """loads list of search results and stores XML in docinfo""" |
511 | 331 |
508 | 332 logging.debug("getSearchResults mode=%s query=%s"%(mode, query)) |
333 if mode == "none": | |
334 return docinfo | |
335 | |
511 | 336 cachedQuery = docinfo.get('cachedQuery', None) |
337 if cachedQuery is not None: | |
338 # cached search result | |
339 if cachedQuery == '%s_%s'%(mode,query): | |
340 # same query | |
341 return docinfo | |
342 | |
343 else: | |
344 # different query | |
345 del docinfo['resultSize'] | |
346 del docinfo['resultXML'] | |
508 | 347 |
511 | 348 # cache query |
349 docinfo['cachedQuery'] = '%s_%s'%(mode,query) | |
509
9d05befdd462
try to get characterNormalization in search result working.
casties
parents:
508
diff
changeset
|
350 |
508 | 351 # fetch full results |
511 | 352 docpath = docinfo['textURLPath'] |
508 | 353 params = {'document': docpath, |
354 'mode': 'text', | |
355 'queryType': mode, | |
356 'query': query, | |
357 'queryResultPageSize': 1000, | |
509
9d05befdd462
try to get characterNormalization in search result working.
casties
parents:
508
diff
changeset
|
358 'queryResultPN': 1, |
9d05befdd462
try to get characterNormalization in search result working.
casties
parents:
508
diff
changeset
|
359 'characterNormalization': pageinfo.get('characterNormalization', 'reg')} |
508 | 360 pagexml = self.getServerData("doc-query.xql",urllib.urlencode(params)) |
361 #pagexml = self.getServerData("doc-query.xql","document=%s&mode=%s&queryType=%s&query=%s&queryResultPageSize=%s&queryResultPN=%s&s=%s&viewMode=%s&characterNormalization=%s&highlightElementPos=%s&highlightElement=%s&highlightQuery=%s"%(docpath, 'text', queryType, urllib.quote(query), pagesize, pn, s, viewMode,characterNormalization, highlightElementPos, highlightElement, urllib.quote(highlightQuery))) | |
362 dom = ET.fromstring(pagexml) | |
363 # page content is in <div class="queryResultPage"> | |
364 pagediv = None | |
365 # ElementTree 1.2 in Python 2.6 can't do div[@class='queryResultPage'] | |
366 alldivs = dom.findall("div") | |
367 for div in alldivs: | |
368 dc = div.get('class') | |
369 # page content div | |
370 if dc == 'queryResultPage': | |
371 pagediv = div | |
372 | |
373 elif dc == 'queryResultHits': | |
511 | 374 docinfo['resultSize'] = getInt(div.text) |
508 | 375 |
510 | 376 if pagediv is not None: |
508 | 377 # store XML in docinfo |
511 | 378 docinfo['resultXML'] = ET.tostring(pagediv, 'UTF-8') |
508 | 379 |
380 return docinfo | |
381 | |
382 | |
383 def getResultsPage(self, mode="text", query=None, pn=None, start=None, size=None, pageinfo=None, docinfo=None): | |
384 """returns single page from the table of contents""" | |
385 logging.debug("getResultsPage mode=%s, pn=%s"%(mode,pn)) | |
516 | 386 # get (cached) result |
387 self.getSearchResults(mode=mode, query=query, pageinfo=pageinfo, docinfo=docinfo) | |
508 | 388 |
511 | 389 resultxml = docinfo.get('resultXML', None) |
508 | 390 if not resultxml: |
391 logging.error("getResultPage: unable to find resultXML") | |
392 return "Error: no result!" | |
393 | |
394 if size is None: | |
511 | 395 size = pageinfo.get('resultPageSize', 10) |
508 | 396 |
397 if start is None: | |
398 start = (pn - 1) * size | |
399 | |
400 fullresult = ET.fromstring(resultxml) | |
401 | |
510 | 402 if fullresult is not None: |
508 | 403 # paginate |
511 | 404 first = start-1 |
508 | 405 len = size |
406 del fullresult[:first] | |
407 del fullresult[len:] | |
408 tocdivs = fullresult | |
409 | |
410 # check all a-tags | |
411 links = tocdivs.findall(".//a") | |
412 for l in links: | |
413 href = l.get('href') | |
414 if href: | |
511 | 415 # assume all links go to pages |
416 linkUrl = urlparse.urlparse(href) | |
417 linkParams = urlparse.parse_qs(linkUrl.query) | |
418 # take some parameters | |
419 params = {'pn': linkParams['pn'], | |
420 'highlightQuery': linkParams.get('highlightQuery',''), | |
421 'highlightElement': linkParams.get('highlightElement',''), | |
422 'highlightElementPos': linkParams.get('highlightElementPos','') | |
423 } | |
424 url = self.getLink(params=params) | |
425 l.set('href', url) | |
508 | 426 |
427 return serialize(tocdivs) | |
428 | |
429 return "ERROR: no results!" | |
430 | |
431 | |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
432 def getToc(self, mode="text", docinfo=None): |
455 | 433 """loads table of contents and stores XML in docinfo""" |
434 logging.debug("getToc mode=%s"%mode) | |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
435 if mode == "none": |
455 | 436 return docinfo |
437 | |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
438 if 'tocSize_%s'%mode in docinfo: |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
439 # cached toc |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
440 return docinfo |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
441 |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
442 docpath = docinfo['textURLPath'] |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
443 # we need to set a result set size |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
444 pagesize = 1000 |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
445 pn = 1 |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
446 if mode == "text": |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
447 queryType = "toc" |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
448 else: |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
449 queryType = mode |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
450 # number of entries in toc |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
451 tocSize = 0 |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
452 tocDiv = None |
455 | 453 # fetch full toc |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
454 pagexml = self.getServerData("doc-query.xql","document=%s&queryType=%s&queryResultPageSize=%s&queryResultPN=%s"%(docpath,queryType, pagesize, pn)) |
455 | 455 dom = ET.fromstring(pagexml) |
456 # page content is in <div class="queryResultPage"> | |
457 pagediv = None | |
458 # ElementTree 1.2 in Python 2.6 can't do div[@class='queryResultPage'] | |
459 alldivs = dom.findall("div") | |
460 for div in alldivs: | |
461 dc = div.get('class') | |
462 # page content div | |
463 if dc == 'queryResultPage': | |
464 pagediv = div | |
465 | |
466 elif dc == 'queryResultHits': | |
458 | 467 docinfo['tocSize_%s'%mode] = getInt(div.text) |
455 | 468 |
510 | 469 if pagediv is not None: |
455 | 470 # store XML in docinfo |
471 docinfo['tocXML_%s'%mode] = ET.tostring(pagediv, 'UTF-8') | |
472 | |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
473 return docinfo |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
474 |
482
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
475 def getTocPage(self, mode="text", pn=None, start=None, size=None, pageinfo=None, docinfo=None): |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
476 """returns single page from the table of contents""" |
455 | 477 logging.debug("getTocPage mode=%s, pn=%s"%(mode,pn)) |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
478 if mode == "text": |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
479 queryType = "toc" |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
480 else: |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
481 queryType = mode |
455 | 482 |
483 # check for cached TOC | |
484 if not docinfo.has_key('tocXML_%s'%mode): | |
485 self.getToc(mode=mode, docinfo=docinfo) | |
486 | |
487 tocxml = docinfo.get('tocXML_%s'%mode, None) | |
488 if not tocxml: | |
489 logging.error("getTocPage: unable to find tocXML") | |
482
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
490 return "Error: no table of contents!" |
455 | 491 |
482
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
492 if size is None: |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
493 size = pageinfo.get('tocPageSize', 30) |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
494 |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
495 if start is None: |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
496 start = (pn - 1) * size |
455 | 497 |
498 fulltoc = ET.fromstring(tocxml) | |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
499 |
510 | 500 if fulltoc is not None: |
455 | 501 # paginate |
482
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
502 first = (start - 1) * 2 |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
503 len = size * 2 |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
504 del fulltoc[:first] |
456 | 505 del fulltoc[len:] |
455 | 506 tocdivs = fulltoc |
507 | |
508 # check all a-tags | |
509 links = tocdivs.findall(".//a") | |
510 for l in links: | |
511 href = l.get('href') | |
512 if href: | |
513 # take pn from href | |
514 m = re.match(r'page-fragment\.xql.*pn=(\d+)', href) | |
515 if m is not None: | |
476 | 516 # and create new url (assuming parent is documentViewer) |
517 url = self.getLink('pn', m.group(1)) | |
518 l.set('href', url) | |
455 | 519 else: |
520 logging.warning("getTocPage: Problem with link=%s"%href) | |
521 | |
482
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
522 # fix two-divs-per-row with containing div |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
523 newtoc = ET.Element('div', {'class':'queryResultPage'}) |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
524 for (d1,d2) in zip(tocdivs[::2],tocdivs[1::2]): |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
525 e = ET.Element('div',{'class':'tocline'}) |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
526 e.append(d1) |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
527 e.append(d2) |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
528 newtoc.append(e) |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
529 |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
530 return serialize(newtoc) |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
531 |
7ca8ac7db06e
more new template stuff. more batching methods in documentViewer.
casties
parents:
478
diff
changeset
|
532 return "ERROR: no table of contents!" |
455 | 533 |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
534 |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
535 def manage_changeMpdlXmlTextServer(self,title="",serverUrl="http://mpdl-text.mpiwg-berlin.mpg.de/mpdl/interface/",timeout=40,RESPONSE=None): |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
536 """change settings""" |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
537 self.title=title |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
538 self.timeout = timeout |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
539 self.serverUrl = serverUrl |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
540 if RESPONSE is not None: |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
541 RESPONSE.redirect('manage_main') |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
542 |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
543 # management methods |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
544 def manage_addMpdlXmlTextServerForm(self): |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
545 """Form for adding""" |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
546 pt = PageTemplateFile("zpt/manage_addMpdlXmlTextServer", globals()).__of__(self) |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
547 return pt() |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
548 |
453
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
549 def manage_addMpdlXmlTextServer(self,id,title="",serverUrl="http://mpdl-text.mpiwg-berlin.mpg.de/mpdl/interface/",timeout=40,RESPONSE=None): |
beb7ccb92564
first version using elementtree instead of 4suite xml
casties
parents:
407
diff
changeset
|
550 #def manage_addMpdlXmlTextServer(self,id,title="",serverUrl="http://mpdl-text.mpiwg-berlin.mpg.de:30030/mpdl/interface/",timeout=40,RESPONSE=None): |
129
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
551 """add zogiimage""" |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
552 newObj = MpdlXmlTextServer(id,title,serverUrl,timeout) |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
553 self.Destination()._setObject(id, newObj) |
9404b6c37920
more modular version with separate object MpdlXmlTextServer
casties
parents:
diff
changeset
|
554 if RESPONSE is not None: |
455 | 555 RESPONSE.redirect('manage_main') |
556 | |
557 |