1 # ===================================================================== 2 # groupTagSearch: list pages associated with a specified tag. 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.tag = () 28 cgi.subcat = () 29 cgi.subcat.literal = () 30 cgi.paging = 0 # default is no paging. 31 cgi.scope = () 32 cgi.blksize = () 33 cgi.width = 1 # default. 34 cgi.style = screen # default 35 36 grep_pattern = . # default. 37 search_args = () 38 39 tpl.include.tw.page = /dev/null 40 41 # ===================================================================== 42 # Main program 43 # ===================================================================== 44 45 # Load call arguments. 46 csaGetArgs GET 47 48 ~ $'cgi.paging' 0 && csaTrue $TNS_PAGER_DEFAULT && cgi.paging = 1 49 50 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 51 52 . $CSA_ROOT/lib/group-stuff.rc 53 54 . $CSA_ROOT/lib/group-editor.rc 55 56 # Check other required args. 57 ~ $'cgi.tag' () && csaExit.fault 0038 58 59 # Set template vars to provisonal values. 60 tpl.var.tw.page = tw-tag-search 61 tpl.var.tw.page.object = $'tpl.var.tw.page' 62 tpl.var.tw.tags = $'cgi.tag' 63 tpl.var.html.title = $'tpl.var.tw.group'/$'tpl.var.tw.page' 64 65 if (csaIsFullPath --exists --quiet $CSA_TPL_ROOT/tw-tag-search.txt) { 66 # custom template. 67 tpl.include.html.body = $CSA_TPL_ROOT/tw-tag-search.txt 68 } else { 69 # default template. 70 tpl.include.html.body = $tw_dstem/tw-tag-search.txt 71 } 72 73 . $CSA_ROOT/lib/tpl-stuff.rc 74 75 # In the following code I do not normally test for errors after grep(1) 76 # since the latter may pick no lines (and thus exit non-zero) even under 77 # normal circumstances. 78 79 # If full-text tag search was requested use grep(1), 80 # otherwise use a *much* more efficient indexed search. 81 82 csaMkTemp tpl.include.tw.page 83 84 if (~ $'cgi.scope' f) { 85 86 filtertable --input $tw_gstem/tag+dat -- \ 87 grep -ie '^[^'$tab']*'$'cgi.tag' > $'tpl.include.tw.page' 88 89 } else { 90 91 # Perform indexed search. 92 ~ $'cgi.tag' *M:* || search_args = --fold 93 keysearch $search_args $'cgi.tag' \ 94 $tw_gstem/tag+dat > $'tpl.include.tw.page' || 95 csaExit.fault 1020 $'cgi.tag' 96 } 97 98 # For subcat filtering to be reliable it must be done against 99 # unixified page names. Unlike what happens in 'groupPageMap', 100 # no fuzzy category names are accepted here, only exact ones. 101 102 ~ $'cgi.subcat' too.short && cgi.subcat = () 103 104 if (~ $'cgi.subcat' [a-z]*) { 105 106 grep_pattern = '^[^'$tab']+'$tab$'cgi.subcat'^\. 107 108 cp $'tpl.include.tw.page' $tmp1 || csaExit.fault 0003 cp # rewind 109 110 filtertable --input $tmp1 -- \ 111 grep -iEe $grep_pattern > $'tpl.include.tw.page' 112 } 113 114 # If sorting on a column other than those contained in tag+dat was 115 # requested then assume we need to join the result with the page+dat 116 # table first. It is the webmaster's responsibility to ensure that the 117 # specified sort column actually exists in page+dat, as this program 118 # makes no provisions to enforce such requirement. 119 120 if (!~ $TNS_TAG_LIST_SORT k_tag (k tag)^_page) { 121 122 sorttable --input $'tpl.include.tw.page' k_page > $tmp1 || 123 csaExit.fault 0003 sorttable 124 125 # Now join with page+dat. There are no actual integrity constraints 126 # between the two tables being joined, so no PLS is really needed. 127 # Note that the only way to have also 'p_descr' on output it to 128 # specify a sorting column belonging to page+dat (such as 'p_name') 129 # as opposed to tag+dat (see above). 130 131 jointable --column k_page $tmp1 $tw_gstem/page+dat | 132 sorttable $TNS_TAG_LIST_SORT | 133 awktable -- 'BEGIN{ print "\001k_tag\t\001k_page\t\001tag_page" \ 134 "\t\001p_descr\t\001k_node\t\001p_link\t\001p_store" \ 135 "\t\001p_etime\t\001p_vtime\t\001p_ctime" 136 } 137 138 # Safety-measure for backward compatibility. 139 !p_etime {p_etime = 99} 140 141 # Handle page expiration dates. 142 { 143 # Set default expiration date. 144 if ($p_etime == "") $p_etime = "9999-12-31 23:59:59" 145 if ("'$CSA_TIME_ISO'" >= $p_etime && \ 146 $p_descr !~ /^ *-/) $p_descr = "-" $p_descr 147 } 148 149 # Exclude redirected pages if non-editor (not done at the moment). 150 #$p_descr ~ /\(:redirect / && ENVIRON["TNS_AUTH_GRP"] !~ /,editor,/{next} 151 152 # Unconditionally exclude hidden pages with no title, as they are 153 # to be considered logically deleted and the editor will only be 154 # able to edit them through the RESTful interface. 155 $p_descr ~ /^ *-[- ]*$/ {next} 156 157 # Exclude hidden pages (with non-empty title) if non-editor. 158 $p_descr ~ /^ *-[- ]*[^- ]/ && ENVIRON["TNS_AUTH_GRP"] !~ /,editor,/{next} 159 160 # Exclude restricted pages unless authorized user or editor. 161 # This is currently not done, see the comments in "updatePage" 162 # about why I prefer not to be absolutely water-tight. 163 #{ auth_ = "(,editor,|," $p_allow ",)" } 164 #$p_allow != "" && ENVIRON["TNS_AUTH_GRP"] !~ auth_ {next} 165 166 # Remove any explicit exclusion directive. 167 {sub(/^ *! */,"",$p_descr)} 168 169 # Remove any redirection URL from visible description. 170 {sub(/ *\+*\(:redirect .*/,"",$p_descr)} 171 172 { print $k_tag,$k_page,$tag_page,$p_descr,\ 173 $k_node,$p_link,$p_store,$p_etime,$p_vtime,$p_ctime }' \ 174 > $'tpl.include.tw.page' || 175 csaExit.fault 0003 jointable/sorttable/awktable 176 } 177 178 # Static views do not correspond to actual pages on disk, 179 # so we need to toggle unapplicable sections in templates. 180 181 tpl.if.tw.ispage = '(::DEL:)' 182 tpl.fi.tw.ispage = '(:DEL::)' 183 tpl.if.tw.printable = '(::DEL:)' 184 tpl.fi.tw.printable = '(:DEL::)' 185 tpl.if.tw.isview = () 186 tpl.fi.tw.isview = () 187 188 csaExit.ok --table $'tpl.include.tw.page' $tpl_file 189 190 # End of program.