1 # ===================================================================== 2 # cmtView: show the specified TW page comment. 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 # Local variables and functions 23 # ===================================================================== 24 25 cgi.group = () 26 cgi.group.literal = () 27 cgi.page = () 28 cgi.page.literal = () 29 cgi.cmt.new = () 30 cgi.cmt.parent = () 31 cgi.style = () 32 cgi.paging = 0 # default is no paging. 33 cgi.author = () 34 35 captcha_code = () 36 tpl_body = show 37 38 # ===================================================================== 39 # Main program 40 # ===================================================================== 41 42 # Load call arguments. 43 csaGetArgs GET 44 45 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 46 47 . $CSA_ROOT/lib/group-stuff.rc 48 49 . $CSA_ROOT/lib/group-editor.rc 50 51 . $CSA_ROOT/lib/page-stuff.rc 52 53 . $CSA_ROOT/lib/tpl-stuff.rc 54 55 # Prepare the error message "back" button. 56 57 #if (csaIsFullPath --exists --quiet $CSA_TPL_ROOT/tw-nav-back.txt) { 58 # # custom "back" action template. 59 # tpl.include.nav.next = $CSA_TPL_ROOT/tw-nav-back.txt 60 #} else { 61 # # default "back" action template. 62 # tpl.include.nav.next = $tw_dstem/tw-nav-back.txt 63 #} 64 65 ~ $'cgi.style' print && tpl_body = print 66 67 if (!csaIsFullPath --exists --quiet $tw_pstem+cmt) { 68 69 # Test whether comments are explicitly disabled for this page. 70 71 csaIsFullPath --exists --quiet \ 72 $tw_gstem/.$'cgi.page'+cmt && csaExit.fault --back 1013 73 74 # Proceed only if comments are allowed for this group. 75 csaTrue $TNS_CMT_ENABLE || csaExit.fault --back 1013 76 77 # Set Principal Lock Semaphore(s) (PLS). Unfortunately the lock 78 # needs to be set on the 'recent-comment' table, which is common to 79 # all pages within a group; this may become a bottleneck in case of 80 # heavily commented groups. 81 82 csaLock $tw_gstem/recent-comment+dat || csaExit.fault 83 84 # Make sure neither tables were created in the meantime. 85 86 csaIsFullPath --exists --quiet \ 87 $tw_gstem/.$'cgi.page'+cmt && csaExit.fault 1013 88 89 if (!csaIsFullPath --exists --quiet $tw_pstem+cmt) { 90 maketable --input $CSA_ROOT/lib/comment.xrf > $tw_pstem+cmt || 91 csaExit.fault 0003 maketable 92 } 93 } 94 95 # Check authorizations. An empty group list means that everyone 96 # can read this comment. Editors are granted access in any case. 97 98 if (!~ $'tbl_page.p_allow' ()) { 99 100 if (!csvMatch $TNS_AUTH_GRP $'tbl_page.p_allow',editor) { 101 102 # Show self-registration form if appropriate. 103 csaIsInteractive && !csaTrue $CSA_AUTH_OK && 104 ~ $TNS_SELFREG_AUTH *[a-z]* && csaTrue $TNS_SELFREG_AUTOASK && 105 csaExit.location $CSA_RPC_URI'?0=showStatic&x-csa-lang='$CSA_LANG^'&1='$'cgi.group'^'&2=tw-reg-form' 106 107 csaExit.needauth 108 } 109 } 110 111 # Check misc. required args. 112 ~ $'cgi.cmt.new' () && csaExit.fault 0066 # should not occur 113 114 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 115 116 if (csaIsFullPath --exists --quiet $CSA_TPL_ROOT/tw-$tpl_body-comment.txt) { 117 # custom template. 118 tpl.include.html.body = $CSA_TPL_ROOT/tw-$tpl_body-comment.txt 119 } else { 120 # default template. 121 tpl.include.html.body = $tw_dstem/tw-$tpl_body-comment.txt 122 } 123 124 # Now load the requested comment data. Note that the actual comment 125 # body may be large, so I exclude it from the data loaded in env. 126 # Warning: the comment table isn't sorted on the primary key, so a 127 # linear search is needed. Also, I need to know what paged block 128 # the requested comment belongs into, hence the use of 'awktable' to 129 # make the needed on-the-fly calculations as opposed to other simpler 130 # operators. 131 132 awktable -i $tw_pstem+cmt '-vparent_='$'cgi.cmt.parent' \ 133 '-vblksize_='$TNS_PAGER_BLKSIZE(2) -- ' 134 BEGIN { 135 print "k_cmt\t\001c_parent\t\001c_thread\t\001c_tree\t\001c_seq" \ 136 "\t\001c_ctime\t\001c_creau\t\001c_aumail\t\001c_auweb" \ 137 "\t\001c_creip\t\001c_banned\t\001c_approved\t\001c_other" \ 138 "\t\001c_subject\t\001c_excerpt\t\001k_node\t\001blkno_" 139 if ((blksize_/=1) <= 0) blksize_ = 10 140 blkno_ = 1 141 } 142 ++nr_ > blksize_ { blkno_++; nr_ = 0 } 143 $k_cmt == parent_ { 144 print $k_cmt,$c_parent,$c_thread,$c_tree,$c_seq,$c_ctime,$c_creau,\ 145 $c_aumail,$c_auweb,$c_creip,$c_banned,$c_approved,$c_other,\ 146 $c_subject,$c_excerpt,$k_node,blkno_ 147 exit 148 } ' | csa-tbl2rc --prefix tbl_pcmt. > $tmp1 149 150 . $tmp1 151 152 # Since a comment can be banned but it cannot be removed, if a 153 # nonexistent comment was specified I assume that the user is 154 # hacking around and I simply send her to the main listing. 155 156 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 157 158 ~ $'tbl_pcmt.k_cmt' $'cgi.cmt.parent' || csaExit.location \ 159 $CSA_RPC_URI/$CSA_LANG/$'tbl_group.g_uri'/$'tbl_page.p_uri'/comment 160 161 ~ $'tbl_pcmt.c_parent' $'cgi.cmt.parent' || tpl.var.nls.1 = 'Re: ' 162 163 tpl.var.tw.page.cmt.last = $'cgi.cmt.parent' 164 cgi.paging = $'tbl_pcmt.blkno_' 165 166 # Save the current comment ID into session. 167 csaSession.set $'cgi.cmt.parent' 14 168 169 # Now store the comment body to a separate file. 170 171 csaMkTemp tpl.include.tw.^(page page2) 172 173 if (~ $'tbl_pcmt.c_banned' ()) { 174 175 filtertable --input $tw_pstem+cmt -- grep -e '^'$'cgi.cmt.parent'$tab | 176 getcolumn --no-header c_text > $'tpl.include.tw.page' 177 178 # Prepare also a javascript-encoded version of the same content. 179 sed -e 's,\\,\\134,g;s,/,\\057,g;s,<,\\074,g' \ 180 -e 's,>,\\076,g;s,",\\042,g;s,'',\\047,g' \ 181 $'tpl.include.tw.page' > $'tpl.include.tw.page2' || 182 csaExit.fault 0003 sed 183 184 # Make sure no-replace mode is used on the page body by prepending 185 # its name with '-', or any user-supplied CSA tags in the text will 186 # be happily parsed by _envtoxml() !! 187 188 tpl.include.tw.page = -$'tpl.include.tw.page' 189 tpl.include.tw.page2 = -$'tpl.include.tw.page2' 190 191 tpl.if.tw.local.not.banned = () 192 tpl.fi.tw.local.not.banned = () 193 194 } else { 195 196 filtertable --input $tw_pstem+cmt -- grep -e '^'$'cgi.cmt.parent'$tab | 197 getcolumn --no-header c_text > $'tpl.include.tw.page2' 198 199 if (csaIsFullPath --exists --quiet $CSA_TPL_ROOT/tw-banned-body.txt) { 200 # custom template. 201 tpl.include.tw.page = $CSA_TPL_ROOT/tw-banned-body.txt 202 } else { 203 # default template. 204 tpl.include.tw.page = $tw_dstem/tw-banned-body.txt 205 } 206 207 tpl.if.tw.local.not.banned = '(::DEL:)' 208 tpl.fi.tw.local.not.banned = '(:DEL::)' 209 } 210 211 csaStatus || csaExit.fault 0003 filtertable/getcolumn 212 213 # Set comment template vars to their final values. 214 tpl.var.tw.cmt.parent.subject = $'tbl_pcmt.c_subject' 215 tpl.var.tw.cmt.parent.id = $'cgi.cmt.parent' 216 * = ``(' ':T+-){echo -n $'tbl_pcmt.c_ctime'} 217 tpl.var.tw.cmt.parent.date = $1-$2-$3 218 tpl.var.tw.cmt.parent.time = $4:$5:$6 219 tpl.var.tw.paging = $'cgi.paging' 220 tpl.var.tw.cmt.aumail.md5 = $'tbl_pcmt.c_other' 221 222 # Set other needed values in response template. 223 tpl.var.tw.author = $'cgi.author' 224 ~ $CSA_SESSION(13) *'@'*.* && tpl.var.tw.author.email = $CSA_SESSION(13) 225 226 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 227 228 csaMkTemp tpl.include.tw.page.captcha 229 captcha_code = `{pwgen -1 -A -B 6} 230 ~ $bqstatus 0 || csaExit.fault 0003 pwgen 231 csaSession.set $captcha_code 10 232 echo $captcha_code | figlet -w 80 -k > $'tpl.include.tw.page.captcha' 233 csaStatus || csaExit.fault 0003 figlet 234 235 # This can be useful to avoid requesting the captcha code if desired, 236 # by turning the relevant form field from type=text to type=hidden 237 # value=$[tpl.var.tw.captcha:x] 238 239 tpl.var.tw.captcha = $captcha_code 240 241 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 242 243 # Switch local template conditionals as appropriate. 244 245 if (~ ,$TNS_AUTH_GRP, *,editor,*) { 246 if (~ $'tbl_pcmt.c_banned' ()) { 247 tpl.if.tw.local.restore = '(::DEL:)' 248 tpl.fi.tw.local.restore = '(:DEL::)' 249 } else { 250 tpl.if.tw.local.ban = '(::DEL:)' 251 tpl.fi.tw.local.ban = '(:DEL::)' 252 } 253 254 } else { 255 256 tpl.if.tw.local.restore = '(::DEL:)' 257 tpl.fi.tw.local.restore = '(:DEL::)' 258 tpl.if.tw.local.ban = '(::DEL:)' 259 tpl.fi.tw.local.ban = '(:DEL::)' 260 } 261 262 # This view does not correspond to an actual page on disk, 263 # so we need to toggle unapplicable sections in templates. 264 265 tpl.if.tw.ispage = '(::DEL:)' 266 tpl.fi.tw.ispage = '(:DEL::)' 267 #tpl.if.tw.printable = '(::DEL:)' 268 #tpl.fi.tw.printable = '(:DEL::)' 269 tpl.if.tw.isview = () 270 tpl.fi.tw.isview = () 271 272 tpl.var.tw.page.object = $'tpl.var.tw.page.object'/comment/$'cgi.cmt.parent' 273 274 csaExit.ok $tpl_file 275 276 # End of program.