+#!/bin/sh
+
+id="$(checkid "${PATH_INFO#/}")"
+file="${_DATA}/${id}"
+
+#cancel if poll is invalid
+[ "$id" -a -f "$file" ] || REDIRECT "$_BASE/"
+
+tkey() {
+ # convert time stamps for use in POST keys
+ local str="$1" out
+ while [ "$str" ]; do
+ case $str in
+ :*) out="${out}.";;
+ *) out="${out}${str%"${str#?}"}";;
+ esac
+ str="${str#?}"
+ done
+ printf %s "$out"
+}
+
+timelist() {
+ local dates todall splittimes
+ local date tod todsplit
+
+ if [ "$splittimes" = no -a "$dates" -a "$todall" ]; then
+ for date in $dates; do for tod in $todall; do
+ printf %s\\n "${date}_${tod%-}"
+ done ;done
+
+ elif [ "$splittimes" = no -a "$dates" ]; then
+ for date in $dates; do
+ printf %s\\n "${date}"
+ done
+
+ elif [ "$splittimes" = no -a "$todall" ]; then
+ for tod in $todall; do
+ printf %s\\n "${tod%-}"
+ done
+
+ elif [ "$splittimes" = yes ]; then
+ for date in $dates; do
+ todsplit="$(DBM "$file" get "tod_$date")"
+ [ "$todsplit" ] \
+ && for tod in $todsplit; do printf %s\\n "${date}_${tod%-}"; done \
+ || printf %s\\n "${date}"
+ done
+
+ else
+ return 1
+
+ fi
+}
+
+table_poll() {
+ local splittimes="$(DBM "$file" get splittimes || printf no)"
+ local dates="$(DBM "$file" get dates)"
+ local todall="$(DBM "$file" get todall)"
+ local timelist="$(timelist)"
+ local time date span name
+
+ [ "$timelist" ] || return 1
+
+ printf '[table .poll [thead\n'
+ # date header
+ if [ "$dates" ]; then
+ printf '[tr .dates [th]'
+ for date in $dates; do
+ span=0; for time in $timelist; do case $time in
+ ${date}*) span=$((span + 1));;
+ esac; done
+ date -d "$date" +"[th colspan=\"${span}\" . %A <br/> %B %_d, %Y]";
+ done
+ printf '[th]]\n'
+ fi
+
+ # tod header
+ if [ "$splittimes" = yes -o "$todall" ]; then
+ printf '[tr .tod [th]'
+ for time in $timelist; do
+ [ "${time#*_}" = "${time}" ] && time="${time}_"
+ printf '[th . %s]' "${time#*_}"
+ done
+ printf '[th]]\n'
+ fi
+
+ printf '][tbody\n'
+
+ { DBM "$file" get participants; printf \\n; } |while read -r name; do
+ yes="$(DBM "$file" get "reply_yes_${name}")"
+ no="$(DBM "$file" get "reply_no_${name}")"
+ maybe="$(DBM "$file" get "reply_maybe_${name}")"
+
+ printf '[tr [th .name . %s]' "$(HTML "$name")"
+ for time in $timelist; do
+ printf %s "$yes" |grep -qwF "$time" && printf '[td .yes Yes]' && continue
+ printf %s "$no" |grep -qwF "$time" && printf '[td .no No]' && continue
+ printf %s "$maybe" |grep -qwF "$time" && printf '[td .maybe Maybe]' && continue
+ printf '[td .missing . ?]'
+ done
+ printf '[td]]'
+ done
+
+ # Submit line
+ printf '[tr .new [td [input name="name" value="" placeholder="Your Name" autocomplete=off]]'
+ for time in $timelist; do
+ time="$(tkey "$time")"
+ printf '[td [radio "%s" "yes" #yes_%s][label for="yes_%s" Yes]
+ [radio "%s" "no" #no_%s][label for="no_%s" No]
+ [radio "%s" "maybe" #maybe_%s][label for="maybe_%s" Maybe]
+ ]' "${time}" "${time}" "${time}" \
+ "${time}" "${time}" "${time}" \
+ "${time}" "${time}" "${time}"
+ done
+ printf '[td [submit "new" "new" Submit]]]\n'
+
+ printf ']]'
+}
+
+if [ "$REQUEST_METHOD" = POST ]; then
+ local name="$(POST name |grep -m 1 -xE '.*[^ ].*')"
+ local splittimes="$(DBM "$file" get splittimes || printf no)"
+ local dates="$(DBM "$file" get dates)"
+ local todall="$(DBM "$file" get todall)"
+ local timelist="$(timelist)"
+ local time yes no maybe reply
+
+ if [ "$(POST new)" = new ]; then
+ if [ ! "$name" ]; then
+ REDIRECT "${_BASE}${PATH_INFO}#ERROR_NONAME"
+ elif DBM "$file" get participants |grep -qxF "$name"; then
+ REDIRECT "${_BASE}${PATH_INFO}#ERROR_NAMEEXISTS"
+ fi
+ DBM "$file" append participants "${BR}${name}" || DBM "$file" insert participants "${name}" \
+ || REDIRECT "${_BASE}${PATH_INFO}#ERROR_DBACCESS"
+
+ for time in $timelist; do reply="$(POST "$(tkey "$time")")"; case $reply in
+ yes) yes="${yes}${yes:+ }${time}";;
+ no) no="${no}${no:+ }${time}";;
+ maybe) maybe="${maybe}${maybe:+ }${time}";;
+ esac; done
+ DBM "$file" set "reply_yes_${name}" "$yes"
+ DBM "$file" set "reply_no_${name}" "$no"
+ DBM "$file" set "reply_maybe_${name}" "$maybe"
+ REDIRECT "${_BASE}${PATH_INFO}"
+ fi
+
+else
+ pagename="$(pagename "$id")"
+
+ yield_page "$pagename" poll <<-EOF
+ [form method=POST
+ [section .description
+ [h1 .title $(HTML "$pagename")]
+ $(DBM "$file" get description |markdown)
+ ]
+ $(table_poll || printf '[p Poll parameters are invalid]')
+ ]
+ EOF
+fi