]> git.plutz.net Git - shellwiki/blob - searchindex.sh
type for verbose logging
[shellwiki] / searchindex.sh
1 #!/bin/sh
2
3 export _EXEC="${0%/*}/" _DATA="."
4 verb="" v=0 cmd="" force="" location=""
5
6 help() {
7   ex="$1"
8
9   cat >&2 <<-EOF
10         USAGE:
11
12         ${0##*/} prune [--exec "INSTALL_DIR"] [--data "SITE_DIR"] [-v]
13
14         ${0##*/} index [--exec "INSTALL_DIR"] [--data "SITE_DIR"] \\
15                        [--location "/PAGE"] [--force] [-v]
16
17         Commands:
18
19         prune
20             Remove outdated records from the database. This is usually
21             more time consuming than index creation. It is generally
22             save to run pruning while the wiki is online, even when
23             pages are being updated. Although in rare cases a search
24             operation may return incomplete results while running on
25             a database being pruned.
26
27             Pruning mode should be called regularly via cron.
28
29         index
30             Add pages to the search index. Pages with a current index
31             will be skipped unless the --force option is provided.
32             Optionally a --location can be provided to add only a
33             part of the document tree.
34
35         When running indexing and pruning together, indexing should be run
36         first and pruning afterwards.
37
38         Pruning becomes necessary with page updates, not during mere read
39         operation. On a medium traffic installation pruning should be run
40         about once a week. 
41         Pruning the index more often than daily will rarely be necessary
42         and with low traffic sites monthly maintenance may be completely
43         fine.
44
45         Options:
46
47         --exec INSTALL_DIR
48             Point to the location of your shellwiki installation. This will
49             default to the path at which the script is called, if it can be
50             determined.
51
52         --data SITE_DIR
53             Point to the location of your site installation. I.e. the directory
54             containing your "pages/" and "index/" dir. Defaults to working
55             directory.
56
57         --force
58             Add pages to index even if they seem to be indexed already.
59
60         --loction /PAGE
61             Index only the given page and its children. The path is given
62             relative to the web root, i.e. without the DATA and "page/"
63             directory.
64
65         -v
66             Be more verbose.
67         EOF
68
69   exit "${ex:-0}"
70 }
71
72 while [ $# -gt 0 ]; do case $1 in
73   --exec|-e) _EXEC="${2%/}"; shift 2;;
74   --data|-d) _DATA="${2%/}"; shift 2;;
75   --verbose|-v) verb=true; shift 1;;
76   --force) force=true; shift 1;;
77   --help) help 0 2>&1;;
78   prune|index)
79     [ ! "$cmd" ] && cmd="$1" || help 1
80     shift 1;;
81   *) help 1;;
82 esac; done
83
84 if ! [ -d "$_DATA/pages/" -a -d "$_DATA/index/" ]; then
85   printf 'ERROR: %s\nTry --help\n' "\"${_DATA}\" does not seem to be a valid site directory" >&2
86   exit 1
87 fi
88 if ! [ -x "$_EXEC/parsers/40_indexer.sh" -a -x "$_EXEC/cgilite/storage.sh" ]; then
89   printf 'ERROR: %s\nTry --help\n' "could not determine shellwiki installation path (tried \"$_EXEC\")" >&2
90   exit 1
91 fi
92 if [ ! "$cmd" ]; then
93   help 1
94 fi
95
96 . "$_EXEC/cgilite/storage.sh"
97
98 prune() {
99   for word in "$_DATA/index"/*; do
100     [ "$word" = "$_DATA/index/*" ] && continue
101   
102     [ "$verb" ] && printf "%${v}s\r%s\r" "" "${word##*/}" >&2
103     v="${#word}"
104     mv -- "$word" "${word}.$$"
105   
106     while read -r date location freq num total; do
107       l="$_DATA/pages$(UNSTRING "$location")#index.flag"
108       d="$(stat -c %Y "$l")" 2>&-
109   
110       if [ "$date" -ge "$d" ] 2>&-; then
111         printf '%i      %s      %f      %i      %i\n' \
112                "$date" "$location" "$freq" "$num" "$total"
113       elif [ "$verb" ]; then
114         printf "%${v}s\rRemoving \"%s\" from \"%s\"\n" "" "$location" "$word" >&2
115       fi
116     done <"${word}.$$" >>"${word}"
117     rm -- "${word}.$$"
118   done
119 }
120
121 index() {
122   export PATH_INFO="" _DATE="$(date +%s)"
123
124   if [ "$location" ]; then
125     location="${location#/}" location="${location%/}"
126     printf %s\\n "/${location}/"
127     find "$_DATA/pages/" -type d -path "$_DATA/pages/${location}/*" -not -name "#*" -printf "/%P/\n"
128   else
129     find "$_DATA/pages/" -type d -not -name "#*" -printf "/%P/\n"
130   fi \
131   | while read PATH_INFO; do
132     [ "$force" ] && rm -f -- "$_DATA/pages/$PATH_INFO/#index.flag"
133     if [ "$_DATA/pages/$PATH_INFO/#page.md" -nt "$_DATA/pages/$PATH_INFO/#index.flag" \
134          -o -f "$_DATA/pages/$PATH_INFO/#page.md" \
135        -a ! -f "$_DATA/pages/$PATH_INFO/#index.flag" ] 2>&-
136   then
137       [ "$verb" ] && printf "%${v}s\r%s\r" "" "$PATH_INFO" >&2
138       v="${#PATH_INFO}"
139       "$_EXEC/parsers/40_indexer.sh" <"$_DATA/pages/$PATH_INFO/#page.md" >/dev/null
140     fi
141   done
142 }
143
144 case $cmd in
145   index) index;;
146   prune) prune;;
147 esac