1 # =====================================================================
2 # groupTagSearch.awk: RPC I/O function for rpclib/groupTagSearch.
3 #
4 # Copyright (c) 2007-2011 Carlo Strozzi
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; version 2 dated June, 1991.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 #
19 # =====================================================================
20
21 # =====================================================================
22 # void _userproc(int mode)
23 # =====================================================================
24
25 function _userproc(mode, value,outfile,i,j,url,tmp1,a,\
26 b,fmt,stem,blkno,curr,first,\
27 last,tot,fmt1,fmt2,fmt3,tmp,\
28 blksize,e,f,f1,f2,f3,buy,c,d,\
29 tmp2,tmp3,w) {
30
31 if (mode == _O_REQUEST) { # request.
32
33 # target group
34 value = _request("1",1)
35
36 # group must not be null and it may not contain the
37 # unescaped ``.'' character.
38
39 if (value != _NULL && value !~ /\./) {
40 _rcset("cgi.group",unixify(value))
41 _rcset("cgi.group.literal",value)
42 }
43
44 # Required tag name to look for.
45
46 value = _request("2",1)
47 gsub(/[\t\r\n<>]+/," ",value) # just in case
48 sub(/^[ _]+/,"",value); sub(/[ _]+$/,"",value)
49
50 # If multiple tags were specified, consider only the 1st one.
51 sub(/ .*/,_NULL,value)
52
53 value = substr(value,1,64); sub(/_+$/,"",value)
54
55 # "My" tags retain original casing for display purposes
56 # (but search is case-insensitive also for them).
57 if (value !~ /^M:/) value = tolower(value)
58
59 #if (value ~ /^[a-zA-Z0-9]/) _rcset("cgi.tag",value)
60 # Strongly non-latin languages require a broader test.
61 if (value != _NULL) _rcset("cgi.tag",value)
62
63 # Optional target meta-category within group, provided it
64 # is at least 3 characters in length. If it is shorter
65 # (but not null), then it is set to a bogus value. Note that
66 # the "too.short" keyword contains one dot, to make sure it
67 # does not collide with an existing subcat named "tooshort"
68
69 if ((value=_request("3",1)) != _NULL) {
70 _rcset("cgi.subcat.literal",value)
71 if (length((value=unixify(value,1))) < 3) value = "too.short"
72 _rcset("cgi.subcat",value)
73 }
74
75 # Optional starting page no. for paged results.
76 if ((value=_request("4",1)/1) > 0) _rcset("cgi.paging",value)
77
78 # Optional full-text tag search mode.
79 if ((value=_request("5",1)) == "f") _rcset("cgi.scope",value)
80
81 # Page visual appearance.
82 value =_request("6",1)
83 if (value ~ /^(p(rint)?|e(mbed)?[1-9]?)$/) _rcset("cgi.style",value)
84
85 # Optional no. of result entries per row.
86 value =_request("7",1)
87 if ((value/=1) > 1 && value < 100) _rcset("cgi.width",value)
88
89 # Optional client-specified results per page. For this to work
90 # across paging, the pager() function needs to be modified to
91 # pass along this parameter to subsequent calls to groupTagSearch.
92 if ((value=_request("8",1)/1) > 0) _rcset("cgi.blksize",value)
93
94 # The following test is necessary since the address could,
95 # at least in theory, have been set to any string by the
96 # remote user, due to how it is handled to cope with stunnel(8)
97 # and the lack of transproxy support in kernel 2.4.x.
98
99 if (_isipaddr(ENVIRON["REMOTE_ADDR"]) == _TRUE)
100 value = ENVIRON["REMOTE_ADDR"]
101 else value = "0.0.0.0"
102
103 _rcset("REMOTE_ADDR",value)
104 }
105
106 else { # response
107
108 outfile = _rcget("tpl.include.tw.page")
109 if (outfile !~ /^\/\.*[a-zA-Z0-9]/)
110 return(_sys("csaExit.fault 0041 outfile"))
111
112 # Set output format string.
113
114 fmt = readfmt("tw-tag-search")
115 gsub(/%/,"%%",fmt) # turn plain '%' into '%%'.
116 gsub(/\\/,"\\\\&",fmt) # turn '\' into '\\'.
117 gsub(/[\n\r]+/,"",fmt) # just in case.
118 tmp1 = fmt
119
120 # Handle custom positioning of output tokens.
121 sub(/.*\[:/,_NULL,tmp1); sub(/:].*/,_NULL,tmp1)
122 tmp1 = _strip(tmp1,_O_MIDDLE)
123 if (tmp1 !~ /^[0-7 ]+$/) tmp = "1 2 3 4 5 6 7"
124
125 # pad missing arg specs with "0".
126 if ((i=split(tmp1,f," ")) < 7) {
127 while (i++ <= 7) tmp1 = tmp1 " 0"
128 i = split(tmp1,f," ")
129 }
130
131 tmp1 = _NULL
132
133 for (j=1; j<=i; j++) {
134 if (j > 7) break # ignore excess arg specs.
135 if (!sub(//,"%s",fmt)) fmt = fmt ""
136 tmp1 = tmp1 " " f[j]
137 }
138
139 # encode any extra markers.
140 gsub(//,"\\<tw:s/\\>",fmt)
141
142 fmt = fmt "\n"
143
144 split(_strip(tmp1),f," "); f[0] = 0
145
146 # Set subcat output format string.
147
148 fmt1 = readfmt("tw-tag-search-subcat")
149 gsub(/%/,"%%",fmt1) # turn plain '%' into '%%'.
150 gsub(/\\/,"\\\\&",fmt1) # turn '\' into '\\'.
151 gsub(/[\n\r]+/,"",fmt1) # just in case.
152 tmp1 = fmt1
153
154 # Handle custom positioning of output tokens.
155 sub(/.*\[:/,_NULL,tmp1); sub(/:].*/,_NULL,tmp1)
156 tmp1 = _strip(tmp1,_O_MIDDLE)
157 if (tmp1 !~ /^[0-8 ]+$/) tmp = "1 2 3 4 5 6 7 8"
158
159 # pad missing arg specs with "0".
160 if ((i=split(tmp1,f1," ")) < 8) {
161 while (i++ <= 8) tmp1 = tmp1 " 0"
162 i = split(tmp1,f1," ")
163 }
164
165 tmp1 = _NULL
166
167 for (j=1; j<=i; j++) {
168 if (j > 8) break # ignore excess arg specs.
169 if (!sub(//,"%s",fmt1)) fmt1 = fmt1 ""
170 tmp1 = tmp1 " " f1[j]
171 }
172
173 # encode any extra markers.
174 gsub(//,"\\<tw:s/\\>",fmt1)
175
176 fmt1 = fmt1 "\n"
177
178 split(_strip(tmp1),f1," "); f1[0] = 0
179
180 # Set subcat block 1st-page output format string.
181
182 fmt3 = readfmt("tw-tag-search-subcat-first")
183 gsub(/%/,"%%",fmt3) # turn plain '%' into '%%'.
184 gsub(/\\/,"\\\\&",fmt3) # turn '\' into '\\'.
185 gsub(/[\n\r]+/,"",fmt3) # just in case.
186 tmp1 = fmt3
187
188 # Handle custom positioning of output tokens.
189 sub(/.*\[:/,_NULL,tmp1); sub(/:].*/,_NULL,tmp1)
190 tmp1 = _strip(tmp1,_O_MIDDLE)
191 if (tmp1 !~ /^[0-9 ]+$/) tmp = "1 2 3 4 5 6 7 8 9"
192
193 # pad missing arg specs with "0".
194 if ((i=split(tmp1,f3," ")) < 9) {
195 while (i++ <= 9) tmp1 = tmp1 " 0"
196 i = split(tmp1,f3," ")
197 }
198
199 tmp1 = _NULL
200
201 for (j=1; j<=i; j++) {
202 if (j > 9) break # ignore excess arg specs.
203 if (!sub(//,"%s",fmt3)) fmt3 = fmt3 ""
204 tmp1 = tmp1 " " f3[j]
205 }
206
207 # encode any extra markers.
208 gsub(//,"\\<tw:s/\\>",fmt3)
209
210 fmt3 = fmt3 "\n"
211
212 split(_strip(tmp1),f3," "); f3[0] = 0
213
214 # Set format string for store-type entries.
215
216 if (ENVIRON["TNS_BUY_CART"] == "paypal")
217 fmt4 = readfmt("tw-tag-search-shop-paypal")
218 else fmt4 = readfmt("tw-tag-search-shop")
219
220 gsub(/%/,"%%",fmt4) # turn plain '%' into '%%'.
221 gsub(/\\/,"\\\\&",fmt4) # turn '\' into '\\'.
222 gsub(/[\n\r]+/,"",fmt4) # just in case.
223 tmp1 = fmt4
224
225 # Handle custom positioning of output tokens.
226 sub(/.*\[:/,_NULL,tmp1); sub(/:].*/,_NULL,tmp1)
227 tmp1 = _strip(tmp1,_O_MIDDLE)
228 if (tmp1 !~ /^[0-6 ]+$/) tmp1 = "1 2 3 4 5 6"
229
230 # This format string may end up inside a comment block of the
231 # parent template, so it may not contain its own comments or
232 # the XML well-formedness may break. Note that this can be done
233 # only after we have consumed the argument positioning specs.
234
235 gsub(/-->/,"\001>",fmt4)
236 gsub(//,_NULL,fmt4)
237 gsub(/\001>/,"-->",fmt4) # restore orphans.
238
239 # pad missing arg specs with "0".
240 if ((i=split(tmp1,f4," ")) < 6) {
241 while (i++ <= 6) tmp1 = tmp1 " 0"
242 i = split(tmp1,f4," ")
243 }
244
245 tmp1 = _NULL
246
247 for (j=1; j<=i; j++) {
248 if (j > 4) break # ignore excess arg specs.
249 if (!sub(//,"%s",fmt4)) fmt4 = fmt4 ""
250 tmp1 = tmp1 " " f4[j]
251 }
252
253 # encode any extra markers.
254 gsub(//,"\\<tw:s/\\>",fmt4)
255
256 split(_strip(tmp1),f4," "); f4[0] = 0
257
258 stem = ENVIRON["CSA_RPC_URI"] "/" \
259 ENVIRON["CSA_LANG"] "/" \
260 _rcget("tbl_group.g_uri")
261
262 # trigger paging if appropriate.
263 if ((blkno=_rcget("cgi.paging"))) {
264 if ((blksize=_rcget("cgi.blksize",1)) == _NULL)
265 blksize = _rcget("TNS_PAGER_BLKSIZE",1)
266 if ((blksize/=1) <= 0) blksize = 10
267 first = blkno * blksize - blksize + 1
268 last = first + blksize - 1
269 }
270
271 # Make sure output file is cleared, in case we are re-using
272 # an old temporary file and we have nothing to print to it.
273 _creat(outfile,_O_TRUNC)
274
275 # read input table:
276 # k_tag, k_page, tag_page \
277 # [,p_descr, k_node, p_link, p_store, p_etime, p_vtime, p_ctime]
278
279 e[0] = _NULL
280 i=j=1
281 w = _rcget("cgi.width",1)
282
283 while (split(_TBLS[1,i++],a,"\t")) {
284
285 if (a[3] == _NULL) a[3] = a[2] # default page name.
286 if (a[4] == _NULL) a[4] = a[3] # default description.
287
288 # Handle page expiration dates, accounting for older
289 # versions of page+dat which may lack that field.
290
291 # Set default expiration date
292 if (a[9] == "") a[8] = "9999-12-31 23:59:59"
293 if (ENVIRON["CSA_TIME_ISO"] >= a[8] && \
294 a[4] !~ /^ *-/) a[4] = "-" a[4]
295
296 # Hidden pages with no title will not appear in the listing
297 # to anybody, while hidden pages with non-null title will
298 # appear in the listing only to editors.
299
300 if (a[4] ~ /^ *-[- ]*$/) continue
301 else if (a[4] ~ /^ *-[- ]*[^- ]/ && \
302 "," ENVIRON["TNS_AUTH_GRP"] "," !~ /,editor,/) continue
303
304 # Decide whether to exclude redirected pages from output.
305 if (a[4] ~ /\(:redirect.*:\)/ &&
306 _bool(_rcget("TNS_REDIR_PROP",2)) == _TRUE) continue
307
308 # Handle store-type items.
309 if (split(a[7],c,/ +/)) {
310
311 # Set default shipping amount if missing.
312 if (c[3] == _NULL) c[3] = "0"
313
314 split(c[1],d,":")
315
316 # Force default unit of measure if missing.
317 if (d[3] == _NULL) d[3] = _nlsmap(_NULL,"units")
318
319 tmp2 = d[1] ":" d[2] ":" d[3]
320
321 # Normalize decimal separators.
322 gsub(/,/,".",c[2])
323
324 split(c[2],d,":")
325
326 # Set default secondary price if missing.
327 if (d[2] == _NULL) d[2] = d[1]
328
329 # Set default VAT percentage if missing.
330 if (d[3] == _NULL) d[3] = 20
331
332 # Rebuild the complete normalized store field.
333 a[7] = tmp2 " " d[1] ":" d[2] ":" d[3] " " c[3]
334 }
335
336 # "I'm Feeling Lucky" function.
337 if (_TBLS[1,0] == 1 && \
338 _bool(_rcget("TNS_GROUP_MISC_PROP",10)) == _TRUE)
339 _sys("csaExit.location " stem "/" _uriencode(a[3]))
340
341 # Handle output paging.
342 if (blkno && ++tot && (++curr < first || curr > last)) continue
343
344 url = stem "/" _uriencode(a[3])
345
346 # Prevent redundant descriptions on output.
347 if (_strip(a[4],_O_MIDDLE) == _strip(a[3],_O_MIDDLE)) a[4] = _NULL
348
349 # Display the "buy" link where applicable.
350
351 split(a[7],b,/[ :]/)
352
353 if (b[2]) {
354
355 if (ENVIRON["TNS_BUY_CART"] == "paypal") {
356
357 # If the PayPal Shopping Cart is being used, then item
358 # price will include VAT and the shipping amount, if any,
359 # will default to the one of the first (or only) shipping
360 # method supported. PayPal prices always include VAT, as it
361 # is quite unlikely that the merchant will use PayPal also
362 # for the invoicing process as opposed to using her own
363 # usual ERP system.
364
365 if (_bool(ENVIRON["TNS_BUY_PRICE_HAS_VAT"]) == _TRUE) {
366 e[1] = b[4]
367 e[2] = b[5]
368 e[6] = sprintf("%.2f",b[7])
369 }
370 else {
371 e[1] = sprintf("%.2f",b[4]+(b[4]/100*b[6]))
372 e[2] = sprintf("%.2f",b[5]+(b[5]/100*b[6]))
373 e[6] = sprintf("%.2f",\
374 b[7]+b[7]/100*ENVIRON["TNS_BUY_SHIP_VAT"])
375 }
376 }
377
378 else {
379 e[1] = b[4]
380 e[2] = b[5]
381 e[6] = sprintf("%.2f",b[7])
382 }
383
384 e[3] = stem "/tw-cart"
385 e[4] = b[1]
386 e[5] = _xmlencode(a[2])
387 buy = sprintf(fmt4,e[f4[1]],\
388 e[f4[2]],e[f4[3]],e[f4[4]],e[f4[5]],e[f4[6]])
389 }
390 else buy = _NULL
391
392 # Pick the appropriate format string depending on whether this
393 # is a subcat entry or not.
394
395 if (split(a[3],b,".") > 1 && (tmp1=getcat(a[3])) != _NULL) {
396 b[2] = a[3]
397 if (tmp1 != _NULL) {
398 tmp1 = "^" _escreg(tmp1 ".")
399 sub(tmp1,_NULL,b[2]) # compute trail.
400 #sub(/^[^.]+\./,_NULL,b[2]) # compute trail.
401 }
402 # not 1st page in subcat.
403 if (b[1] == tmp) {
404 e[1] = _xmlencode(url)
405 e[2] = _xmlencode(b[1])
406 e[3] = _xmlencode(b[2])
407 e[4] = _xmlencode(a[4])
408 e[5] = a[2]
409 e[6] = a[2]; sub(/^[^.]+\./,_NULL,e[6])
410 e[7] = _xmlencode(a[6])
411 e[8] = buy
412 printf(fmt1,e[f1[1]],e[f1[2]],e[f1[3]],e[f1[4]],\
413 e[f1[5]],e[f1[6]],e[f1[7]],e[f1[8]]) > outfile
414 }
415 else {
416 # 1st page in subcat.
417 e[1] = _xmlencode(b[1])
418 e[2] = _xmlencode(url)
419 e[3] = _xmlencode(b[1])
420 e[4] = _xmlencode(b[2])
421 e[5] = _xmlencode(a[4])
422 e[6] = a[2]
423 e[7] = a[2]; sub(/^[^.]+\./,_NULL,e[7])
424 e[8] = _xmlencode(a[6])
425 e[9] = buy
426 printf(fmt3,e[f3[1]],e[f3[2]],e[f3[3]],e[f3[4]],\
427 e[f3[5]],e[f3[6]],e[f3[7]],e[f3[8]],e[f3[9]]) > outfile
428 tmp = b[1]
429 }
430 }
431 else {
432 e[1] = _xmlencode(url)
433 e[2] = _xmlencode(a[3])
434 e[3] = _xmlencode(a[4])
435 e[4] = a[2]
436 e[5] = a[2]; sub(/^[^.]+\./,_NULL,e[5])
437 e[6] = _xmlencode(a[6])
438 e[7] = buy
439 printf(fmt,e[f[1]],e[f[2]],e[f[3]],\
440 e[f[4]],e[f[5]],e[f[6]],e[f[7]]) > outfile
441 }
442
443 # Provide also a machine-readable format.
444 _wsresponse(1,j++,url)
445 }
446
447 close(outfile)
448
449 # show the pager if appropriate.
450 if (blkno && tot > blksize) {
451
452 # Set pager output format string.
453
454 fmt2 = readfmt("tw-pager")
455 gsub(/%/,"%%",fmt2) # turn plain '%' into '%%'.
456 gsub(/\\/,"\\\\&",fmt2) # turn '\' into '\\'.
457 gsub(/[\n\r]+/,"",fmt2) # just in case.
458
459 # the pager format string is currently not customizable.
460 if (!sub(//,"%s",fmt2)) fmt2 = fmt2 ""
461 if (!sub(//,"%s",fmt2)) fmt2 = fmt2 ""
462
463 # encode any extra markers.
464 gsub(//,"\\<tw:s/\\>",fmt2)
465
466 fmt2 = fmt2 "\n"
467
468 url = ENVIRON["CSA_RPC_URI"] "/" \
469 ENVIRON["CSA_LANG"] "/" \
470 _rcget("tbl_group.g_uri") "/9/" _rcget("cgi.tag")
471
472 if ((tmp=_rcget("cgi.subcat")) != _NULL) url = url "/" tmp "/"
473 else url = url "?4="
474
475 tot % blksize ? tmp = 1 : tmp = 0
476
477 _response("tpl.var.tw.pager",\
478 pager(blkno,int(tot/blksize)+tmp,url,fmt2))
479 }
480
481 value = _rcget("tpl.var.tw.tags",1)
482 gsub(/_/," ",value); tmp3 = value
483
484 sub(/^[gkM]:/,_NULL,value)
485 _response("tpl.var.tw.tags",value)
486
487 # Set a meaningful meta description element.
488 value = _rcget("tbl_group.g_descr")
489
490 if (_rcget("cgi.subcat") != _NULL)
491 value = value ": " _rcget("cgi.subcat.literal")
492
493 value = value ": " tmp3
494
495 _response("tpl.var.tw.meta", "")
497
498 # Set also a consistent page title.
499 _response("tpl.var.html.title", value)
500
501 # generic template conditionals.
502
503 ifsections()
504 }
505 }
506
507 # EOF