From: Paul Hänsch Date: Thu, 25 Jan 2024 02:25:19 +0000 (+0100) Subject: month calendar view, more modular architecture X-Git-Url: https://git.plutz.net/?p=shellwiki;a=commitdiff_plain;h=71c5f8ed8020d14fa73c084a14fe3082a3977000 month calendar view, more modular architecture --- diff --git a/macros/calendar b/macros/calendar index 575662f..e2fa8aa 100755 --- a/macros/calendar +++ b/macros/calendar @@ -1,4 +1,5 @@ #!/bin/sh +# vi:syntax=bash # Copyright 2024 Paul Hänsch # @@ -14,6 +15,7 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR # IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + . "$_EXEC/cgilite/cgilite.sh" . "$_EXEC/acl.sh" . "$_EXEC/tools.sh" @@ -28,10 +30,8 @@ while [ $# -gt 0 ]; do case $1 in --depth) depth="$2" shift 2;; \#*) tags="${tags}${tags:+ }${1###}"; shift 1;; \!*) ntags="${ntags}${ntags:+ }${1##!}"; shift 1;; - --h1|--h2|--h3|--h4|--h5|--h6|--label) - labeltype="${1#--}" label="$2"; shift 2;; - --alt-label) - altlabel="$2"; shift 2;; + --date|--from) fromdate="$2"; shift 2;; + --weekstart|--ws|-ws) ws="$2"; shift 2;; --) shift 1; break;; *) if [ ! "$dir" ]; then dir="$1" @@ -47,95 +47,129 @@ esac; done [ "$depth" -ge 0 -o "$depth" -le 0 ] 2>&- || depth=0 read DY DM DD <<-EOF - $(date +"%Y %m %d") + $(isdate "$fromdate" \ + && date -ud "$fromdate" +"%Y %m %d" \ + || date -u +"%Y %m %d" + ) EOF -dstart="$(date -d "${DY}-${DM}-01" +%s)" -[ "$DM" -lt 12 ] \ -&& dend="$(date -d "${DY}-$(( ${DM#0} + 1))-01" +%s)" \ -|| dend="$(date -d "$(( ${DY#0} + 1))-01-01" +%s)" +case $ws in + 0|[sS]*) ws=0;; + 1|[mM]*) ws=1;; + *) ws=0;; +esac + +rrexpand() { + # Recurrence Expansion + # read recurring event specifications and expand them to a list of + # single events within the specified time frame -expand() { - local start="$1" end="$2" rrfreq="$3" rrint="$4" rrend="$5" evtitle="$6" evlink="$7" - local dstart dend + local dstart="$1" dend="$2" + local junk1 start end rrfreq rrint rrend evtitle evlink junk2 + + while read -r junk1 start end rrfreq rrint rrend evtitle evlink junk2; do + [ "$rrend" -eq -1 ] && rrend=9999999999 + + if [ "$start" -lt "$dend" ] && + [ "$end" -gt "$dstart" -o "$rrend" -gt "$dstart" ]; then + case $rrint in + day) rrex_day;; + week) rrex_week;; + month) rrex_month;; + year) rrex_year;; + *): + printf '%i %i %s %s\n' "$start" "$end" "$evtitle" "$evlink" + ;; + esac + fi + done +} + +rrex_day() { + # helper for rrexpand daily/N-day expansion local nstart nend - [ "$rrend" -eq -1 ] && rrend=9999999999 - - case $rrint in - day) - nend=$(( rrfreq * 86400 - (dstart - end) % (rrfreq * 86400) + dstart )) - nstart=$(( start - end + nend)) - debug "[ $nend -lt $dend -a $nstart -lt $rrend ]" - while [ "$nend" -lt "$dend" -a "$nstart" -lt "$rrend" ]; do - printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink" - # printf '%i %i %s\n' "$nstart" "$nend" "$evlink" - nstart="$((nstart + rrfreq * 86400))" - nend="$((nstart - start + end))" - done - ;; - week) - nend=$(( rrfreq * 604800 - (dstart - end) % (rrfreq * 604800) + dstart )) - nstart=$(( start - end + nend)) - while [ "$nend" -lt "$dend" -a "$nstart" -lt "$rrend" ]; do - printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink" - nstart="$((nstart + rrfreq * 7 * 86400))" - nend="$((nstart - start + end))" - done - ;; - month) - { read _y _m _d; read y m d; } <<-EOF - $(date -d @$dstart +"%Y %_m %_d" - date -d @$start +"%Y %_m %_d" + nend=$(( rrfreq * 86400 - (dstart - end) % (rrfreq * 86400) + dstart )) + nstart=$(( start - end + nend)) + while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do + [ "$nstart" -ge "$start" ] \ + && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink" + nstart="$((nstart + rrfreq * 86400))" + nend="$((nstart - start + end))" + done +} + +rrex_week() { + # helper for rrexpand weekly/N-week expansion + local nstart nend + + nend=$(( 0 * 604800 - (dstart - end) % (rrfreq * 604800) + dstart )) + nstart=$(( start - end + nend)) + while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do + [ "$nstart" -ge "$start" -a "$nstart" -ge "$dstart" ] \ + && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink" + nstart="$((nstart + rrfreq * 7 * 86400))" + nend="$((nstart - start + end))" + done +} + +rrex_month() { + # helper for rrexpand monthly/N-month expansion + local nstart nend + + { read _y _m _d; read y m d start_time; } <<-EOF + $(date -ud @$dstart +"%Y %_m %_d" + date -ud @$start +"%Y %_m %_d %T" ) EOF - _m=$((_y * 12 + _m)) m=$((y * 12 + m)) - while :; do - m=$(( rrfreq - ((_m - m - 1) % rrfreq + 1) + _m )) - nstart="$(printf '%04i-%02i-%02i' "$(( (m - 1) / 12 ))" "$(( (m - 1) % 12 + 1 ))" "$d")" - if isdate "$nstart" && [ "$(date -d "$nstart" +%s)" -ge "$dstart" ]; then - break - fi >/dev/null - _m="$((_m + rrfreq))" - done - nstart="$(date -d "$nstart $start_time" +%s)" - nend="$((end - start + nstart))" - while [ "$nend" -lt "$dend" -a "$nstart" -lt "$rrend" ]; do - printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink" - m="$((m + rrfreq))" - nstart="$(printf '%04i-%02i-%02i' "$(( (m - 1) / 12 ))" "$(( (m - 1) % 12 + 1 ))" "$d")" - nstart="$(date -d "$nstart $start_time" +%s)" - nend="$((nstart - start + end))" - done - ;; - year) - { read _y _m _d; read y m d; } <<-EOF - $(date -d @$dstart +"%Y %_m %_d" - date -d @$start +"%Y %_m %_d" + _m=$((_y * 12 + _m)) m=$((y * 12 + m)) + while :; do + m=$(( rrfreq - ((_m - m - 1) % rrfreq + 1) + _m )) + nstart="$(printf '%04i-%02i-%02i' "$(( (m - 1) / 12 ))" "$(( (m - 1) % 12 + 1 ))" "$d")" + if isdate "$nstart" && [ "$(date -ud "$nstart" +%s)" -ge "$dstart" ]; then + break + fi >/dev/null + _m="$((_m + rrfreq))" + done + nstart="$(date -ud "$nstart $start_time" +%s)" + nend="$((end - start + nstart))" + while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do + [ "$nstart" -ge "$start" ] \ + && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink" + m="$((m + rrfreq))" + nstart="$(printf '%04i-%02i-%02i' "$(( (m - 1) / 12 ))" "$(( (m - 1) % 12 + 1 ))" "$d")" + nstart="$(date -ud "$nstart $start_time" +%s)" + nend="$((nstart - start + end))" + done +} + +rrex_year() { + # helper for rrexpand yearly/N-year expansion + local nstart nend + + { read _y _m _d; read y m d start_time; } <<-EOF + $(date -ud @$dstart +"%Y %_m %_d" + date -ud @$start +"%Y %_m %_d %T" ) EOF - while :; do - y=$(( rrfreq - ((_y - y - 1) % rrfreq + 1) + _y )) - nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")" - if isdate "$nstart" && [ "$(date -d "$nstart" +%s)" -ge "$dstart" ]; then - break - fi >/dev/null - _y="$((_y + rrfreq))" - done - nstart="$(date -d "$nstart $start_time" +%s)" - nend="$((end - start + nstart))" - while [ "$nend" -lt "$dend" -a "$nstart" -lt "$rrend" ]; do - printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink" - y="$((y + rrfreq))" - nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")" - nstart="$(date -d "$nstart $start_time" +%s)" - nend="$((nstart - start + end))" - done - ;; - *): - printf '%i %i %s %s\n' "$start" "$end" "$evtitle" "$evlink" - ;; - esac + while :; do + y=$(( rrfreq - ((_y - y - 1) % rrfreq + 1) + _y )) + nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")" + if isdate "$nstart" && [ "$(date -ud "$nstart" +%s)" -ge "$dstart" ]; then + break + fi >/dev/null + _y="$((_y + rrfreq))" + done + nstart="$(date -ud "$nstart $start_time" +%s)" + nend="$((end - start + nstart))" + while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do + [ "$nstart" -ge "$start" ] \ + && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink" + y="$((y + rrfreq))" + nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")" + nstart="$(date -ud "$nstart $start_time" +%s)" + nend="$((nstart - start + end))" + done } events="$( @@ -152,29 +186,96 @@ events="$( then cat "$_DATA/pages/${pagedir}/#events" fi - done \ - | while read -r junk1 tstart tend rrfreq rrint rrend evtitle evlink junk2; do - if [ "$tend" -gt "$dstart" -a "$tstart" -lt "$dend" ] \ - || [ "$rrend" -gt "$dstart" -o "$rrend" -eq -1 ]; then - expand "$tstart" "$tend" "$rrfreq" "$rrint" "$rrend" "$evtitle" "$evlink" - fi - done \ - | debug \ - | sort -n + done )" -lday='' - -printf '' - date -d "@$start" +'
  • ' +cal_list() { + # Print list view for upcoming events + local lday='' events sdate=$(date -ud "${DY}-${DM}-${DD}" +%s) + + events="$( + printf %s\\n "$events" \ + | rrexpand "$sdate" "$((sdate + 42 * 86400))" \ + | sort -n + )" + + printf '' + date -ud "@$start" +'
  • ' +} + +cal_month() { + local ws events calmonth + local iday idow mname dcnt dow dcal start end title link n + + calmonth="$(GET calmonth || printf %i "$((DY * 12 + DM))")" + DY="$(( (calmonth - 1) / 12 ))" + DM="$(( (calmonth - 1) % 12 + 1 ))" + + read -r iday idow mname <<-EOF + $(date -ud "${DY}-${DM}-01" +"%s %u %B") + EOF + dcnt=$((iday - idow * 86400 + ws * 86400)) + dow=$ws + dcal="$(date -ud @"$dcnt" +%d)" + + events="$( + printf %s\\n "$events" \ + | rrexpand "$dcnt" "$((dcnt + 42 * 86400))" \ + | sort -n + )" + + printf '' + printf '' \ + "./?calmonth=$((DY * 12 + DM -1))" "$mname" "./?calmonth=$((DY * 12 + DM + 1))" + for n in 0 1 2 3 4 5 6; do date -ud @"$((dcnt + n * 86400))" +''; done + printf '' + while :; do + [ $dow = $ws ] && printf '' + printf '\n' + [ $dow = $(( (ws + 6) % 7)) ] && printf '\n' + + dcnt=$(( dcnt + 86400 )) + dow=$(( (dow + 1) % 7 )) + [ $dcal -lt 28 ] \ + && dcal=$((dcal + 1)) \ + || dcal=$(date -ud @"$dcnt" +%d) + [ $dcnt -gt $((iday + 28 * 86400)) -a $dcal -le 7 -a $dow = $ws ] \ + && break + done + printf '
    <%s>
    %a
    ' "$dcal" + + evlist="$( + printf %s\\n "$events" \ + | while read start end title link; do + if [ "$((start / 86400))" -lt "$((dcnt / 86400))" -a "$end" -gt "$dcnt" ]; then + printf '
  • %s
  • ' \ + "$(UNSTRING "${link%%#*}" |URL)" \ + "$(UNSTRING "${link#*#}" |URL)" \ + "$(UNSTRING "$title" |HTML)" + elif [ "$((start / 86400))" -eq "$((dcnt / 86400))" ]; then + printf '
  • %s - %s
  • ' \ + "$(date -ud @"$start" +%H:%M)" \ + "$(UNSTRING "${link%%#*}" |URL)" \ + "$(UNSTRING "${link#*#}" |URL)" \ + "$(UNSTRING "$title" |HTML)" + fi + done + )" + [ "$evlist" ] && printf '
      %s
    ' "$evlist" + + printf '
    ' +} + +%rem cal_list +cal_month