]> git.plutz.net Git - webpoll/blob - poll.sh
Fix: proper shorthand-escape for display of admin link
[webpoll] / poll.sh
1 #!/bin/sh
2
3 id="$(checkid "${PATH_INFO#/}")"
4 file="${_DATA}/${id}"
5
6 #cancel if poll is invalid
7 if [ ! "$id" -o ! -f "$file" ]; then
8   page_home;
9   return 0
10 fi
11
12 if expr match "$bookmarks" ".*${id}.*" >/dev/null; then
13   :
14 elif [ "$bookmarks" ]; then
15   SET_COOKIE +$((182 * 86400)) bookmarks="${bookmarks} ${id}" Path="${_BASE}/"
16 fi
17
18 admin="$(expr match "$bookmarks" ".*$id/\([a-zA-Z0-9:=]\{16\}\).*")"
19 admin="$(DBM "$file" get adminkey |grep -xF "$admin")"
20
21 tkey() {
22   # convert time stamps for use in POST keys
23   local str="$1" out
24   while [ "$str" ]; do
25     case $str in
26       :*) out="${out}.";;
27       *) out="${out}${str%"${str#?}"}";;
28     esac
29     str="${str#?}"
30   done
31   printf %s "$out"
32 }
33
34 timelist() {
35   local dates todall splittimes
36   local date tod todsplit
37
38   if [ "$splittimes" = no -a "$dates" -a "$todall" ]; then
39     for date in $dates; do for tod in $todall; do
40       printf %s\\n "${date}_${tod%-}"
41     done ;done
42
43   elif [ "$splittimes" = no -a "$dates" ]; then
44     for date in $dates; do
45       printf %s\\n "${date}"
46     done
47
48   elif [ "$splittimes" = no -a "$todall" ]; then
49     for tod in $todall; do
50       printf %s\\n "${tod%-}"
51     done
52
53   elif [ "$splittimes" = yes ]; then
54     for date in $dates; do
55       todsplit="$(DBM "$file" get "tod_$date")"
56       [ "$todsplit" ] \
57       && for tod in $todsplit; do printf %s\\n "${date}_${tod%-}"; done \
58       || printf %s\\n "${date}"
59     done
60
61   else
62     return 1
63
64   fi
65 }
66
67 table_poll() {
68   local splittimes="$(DBM "$file" get splittimes || printf no)"
69   local dates="$(DBM "$file" get dates)"
70   local todall="$(DBM "$file" get todall)"
71   local timelist="$(timelist)"
72   local edit="$(GET edit)"
73   local time date span name yes no maybe yc nc mc
74
75   [ "$timelist" ] || return 1
76
77   printf '[table .poll [thead\n'
78   # date header
79   if [ "$dates" ]; then
80     printf '[tr .dates [th]'
81     for date in $dates; do
82       span=0; for time in $timelist; do case $time in
83         ${date}*) span=$((span + 1));;
84       esac; done
85       date -d "$date" +"[th colspan=\"${span}\" . %A <br/> %B %_d, %Y]";
86     done
87     printf '[th]]\n'
88   fi
89   
90   # tod header
91   if [ "$splittimes" = yes -o "$todall" ]; then
92     printf '[tr .tod [th]'
93     for time in $timelist; do
94       case $time in
95        *-*-*_*:*) time="${time#*_}";;
96        *-*-*) time="";;
97        *:*);;  # time="${time}"
98       esac
99       printf '[th . %s]' "${time}"
100     done
101     printf '[th]]\n'
102   fi
103
104   printf '][tbody\n'
105
106   # Vote displays
107   { DBM "$file" get participants; printf \\n; } |while read -r name; do
108     [ "$name" = "$edit" ] && continue
109     maybe="$(DBM "$file" get "reply_maybe_${name}")"
110       yes="$(DBM "$file" get "reply_yes_${name}")"
111        no="$(DBM "$file" get "reply_no_${name}")"
112
113     printf '[tr [th .name . %s]' "$(HTML "$name")"
114     for time in $timelist; do
115       printf %s   "$yes" |grep -qwF "$time" && printf '[td   .yes   Yes]' && continue
116       printf %s    "$no" |grep -qwF "$time" && printf '[td    .no    No]' && continue
117       printf %s "$maybe" |grep -qwF "$time" && printf '[td .maybe Maybe]' && continue
118       printf '[td .missing . ?]'
119     done
120     printf '[td .edit [a href="?edit=%s" Edit]]]\n' "$(URL "$name")"
121   done
122
123   if [ "$edit" ]; then
124     maybe="$(DBM "$file" get "reply_maybe_${edit}")"
125       yes="$(DBM "$file" get "reply_yes_${edit}")"
126        no="$(DBM "$file" get "reply_no_${edit}")"
127
128     printf '[tr .new [th .name [submit "delete" "%s" -] %s]' "$(HTML "$edit")" "$(HTML "$edit")"
129     for time in $timelist; do
130       ktime="$(tkey "$time")"
131       printf '[td  [radio "%s"   "yes"   #yes_%s %s][label   for="yes_%s"   Yes]
132                    [radio "%s"    "no"    #no_%s %s][label    for="no_%s"    No]
133                    [radio "%s" "maybe" #maybe_%s %s][label for="maybe_%s" Maybe]
134               ]' "${ktime}" "${time}" "$(checked "$time"   $yes)" "${time}" \
135                  "${ktime}" "${time}" "$(checked "$time"    $no)" "${time}" \
136                  "${ktime}" "${time}" "$(checked "$time" $maybe)" "${time}"
137     done
138     printf '[td [submit "update" "%s" Update]]]\n' "$(HTML "$edit")"
139   else
140
141     # Vote counts
142     printf '[tr .votecount [td]'
143     for time in $timelist; do
144       yc=0 nc=0 mc=0
145       { DBM "$file" get participants; printf \\n\\n; } |while read -r name; do
146         [ ! "$name" ] && printf '[td %i (%i)]' "$yc" "$((yc + mc))" && break;
147           yes="$(DBM "$file" get "reply_yes_${name}")"
148            no="$(DBM "$file" get "reply_no_${name}")"
149         maybe="$(DBM "$file" get "reply_maybe_${name}")"
150
151         printf %s   "$yes" |grep -qwF "$time" && yc=$((yc + 1)) && continue
152         printf %s "$maybe" |grep -qwF "$time" && mc=$((mc + 1)) && continue
153       done
154     done
155     printf '[td]]\n'
156
157     # Submit line
158     printf '[tr .new [td [input name="name" value="" placeholder="Your Name" autocomplete=off]]'
159     for time in $timelist; do
160       time="$(tkey "$time")"
161       printf '[td  [radio "%s"   "yes"   #yes_%s][label   for="yes_%s"   Yes]
162                    [radio "%s"    "no"    #no_%s][label    for="no_%s"    No]
163                    [radio "%s" "maybe" #maybe_%s][label for="maybe_%s" Maybe]
164               ]' "${time}" "${time}" "${time}" \
165                  "${time}" "${time}" "${time}" \
166                  "${time}" "${time}" "${time}"
167     done
168     printf '[td [submit "new" "new" Submit]]]\n'
169   fi
170
171   printf ']]'
172 }
173
174 if [ "$REQUEST_METHOD" = POST ]; then
175   local update="$(POST update)" delete="$(POST delete)"
176   local name="$(POST name |grep -m 1 -xE '.*[^  ].*')"
177   local splittimes="$(DBM "$file" get splittimes || printf no)"
178   local dates="$(DBM "$file" get dates)"
179   local todall="$(DBM "$file" get todall)"
180   local timelist="$(timelist)"
181   local time yes no maybe reply
182
183   if [ "$(POST new)" = new -o "$update" ]; then
184     [ "$update" ] && name="$update"
185
186     if [ ! "$name" ]; then
187       REDIRECT "${_BASE}${PATH_INFO}#ERROR_NONAME"
188     elif [ ! "$update" ] && DBM "$file" get participants |grep -qxF "$name"; then
189       REDIRECT "${_BASE}${PATH_INFO}#ERROR_NAMEEXISTS"
190     elif [ "$update" ] && ! DBM "$file" get participants |grep -qxF "$name"; then
191       REDIRECT "${_BASE}${PATH_INFO}#ERROR_NAMENONEXIST"
192     fi
193     if [ ! "$update" ]; then
194       DBM "$file" append participants "${BR}${name}" || DBM "$file" insert participants "${name}" \
195       || REDIRECT "${_BASE}${PATH_INFO}#ERROR_DBACCESS"
196     fi
197
198     for time in $timelist; do reply="$(POST "$(tkey "$time")")"; case $reply in
199         yes)   yes="${yes}${yes:+ }${time}";;
200          no)    no="${no}${no:+ }${time}";;
201       maybe) maybe="${maybe}${maybe:+ }${time}";;
202     esac; done
203     DBM "$file" set "reply_yes_${name}" "$yes"
204     DBM "$file" set "reply_no_${name}" "$no"
205     DBM "$file" set "reply_maybe_${name}" "$maybe"
206
207   elif [ "$delete" ]; then
208     if ! DBM "$file" get participants |grep -qxF "$delete"; then
209       REDIRECT "${_BASE}${PATH_INFO}#ERROR_NAMENONEXIST"
210     fi
211     DBM "$file" set participants "$(DBM "$file" get participants |grep -vxF "$delete")"
212     DBM "$file" delete "reply_yes_${delete}"
213     DBM "$file" delete "reply_no_${delete}"
214     DBM "$file" delete "reply_maybe_${delete}"
215
216   elif [ "$(POST bookmark)" -a ! "$bookmarks" ]; then
217     SET_COOKIE +$((182 * 86400)) bookmarks="${id}" Path="${_BASE}/"
218
219   fi
220   REDIRECT "${_BASE}${PATH_INFO}"
221   
222 else
223   pagename="$(pagename "$id")"
224
225   yield_page "$pagename" poll <<-EOF
226         [form method=POST
227           [section .description
228             [h1 .title $(HTML "$pagename")]
229             $(DBM "$file" get description |markdown)
230           ]
231           $(table_poll || printf '[p Poll parameters are invalid]')
232           $(if [ "$admin" ]; then
233             printf '[section .bookmark You have bookmarked the admin page of this poll: [a href="./%s" modify poll]]' "$(URL ${id}/${admin})"
234           elif [ "$bookmarks" ]; then
235             printf '[section .bookmark This poll has been bookmarked and is accessible via a link on the front page.]'
236           else
237             printf '[section .bookmark Polls are accessible only via their URL. You can set a Cookie to bookmark all polls you visit. Bookmarked polls will be listed on the frontpage.<br/> [submit "bookmark" "add" Set Cookie]]'
238           fi)
239         ]
240         EOF
241 fi