From 306aa2a7d304b7e430ac00ea65aba2dc2756c26e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Paul=20H=C3=A4nsch?= Date: Fri, 17 Nov 2023 11:44:26 +0100 Subject: [PATCH] event macro stubs --- macros/event | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100755 macros/event diff --git a/macros/event b/macros/event new file mode 100755 index 0000000..2bf3b05 --- /dev/null +++ b/macros/event @@ -0,0 +1,269 @@ +#!/bin/sh + +. $_EXEC/cgilite/cgilite.sh +. $_EXEC/cgilite/session.sh + +_(){ printf %s\\n "$*"; } +[ "${LANGUAGE}" -a -r "${_EXEC}/l10n/${LANGUAGE}.sh" ] && . "${_EXEC}/l10n/${LANGUAGE}.sh" + +start_date= start_time= end_date= end_time= +rec_freq= rec_int= error_msg= rec_end= +title= +start= end= nstart= nend= + +isdate(){ + local date="$1" y m d + + if printf %s "$date" \ + | grep -xEq '[0-9]{4}-((01|03|05|07|08|10|12)-(0[1-9]|[12][0-9]|3[01])|(04|06|09|11)-(0[1-9]|[12][0-9]|30)|02-(0[1-9]|[12][0-9]))' + then # y-m-d (ISO Date) + y="${date%%-*}" d="${date##*-}" m="${date%-*}" m="${m#*-}" + elif printf %s "$date" \ + | grep -xEq '((0?1|0?3|0?5|0?7|0?8|10|12)/(0?[1-9]|[12][0-9]|3[01])|(0?4|0?6|0?9|11)/(0?[1-9]|[12][0-9]|30)|0?2-(0[1-9]|[12][0-9]))/([0-9]{2}|[0-9]{4})' + then # m/d/y (US Date) + y="${date##*/}" m="${date%%/*}" d="${date%/*}" d="${d#*/}" + elif printf %s "$date" \ + | grep -xEq '((0?[1-9]|[12][0-9]|3[01])[\./](0?1|0?3|0?5|0?7|0?8|10|12)|(0?[1-9]|[12][0-9]|30)[\./](0?4|0?6|0?9|11)|(0[1-9]|[12][0-9])[\./]0?2)[\./]([0-9]{2}|[0-9]{4})' + then # d/m/y or d.m.y (European Date / German Date) + y="${date##*.}" d="${date%%.*}" m="${date%.*}" m="${m#*.}" + else + return 1 + fi + [ $y -lt 100 -a $y -gt 50 ] && y=$((y + 1900)) + [ $y -lt 100 -a $y -le 50 ] && y=$((y + 2000)) + date="$(printf "%04i-%02i-%02i" $y ${m#0} ${d#0})" + + # leap year + if [ "$m" -eq 2 -a "$d" -eq 29 ]; then + if [ "$((y % 400))" -eq 0 ]; then + : + elif [ "$((y % 100))" -eq 0 ]; then + return 1 + elif [ "$((y % 4))" -eq 0 ]; then + : + else + return 1 + fi + fi + + printf '%04i-%02i-%02i\n' "$y" "${m#0}" "${d#0}" + return 0 +} + +istime(){ + time="$1" h= m= + + if printf %s "$time" | grep -xEq '(0?[1-9]|1[012])(:[0-5][0-9])? ?(am|AM)\.?'; then + time="${time%?[aA][mM]}" h="${time%:*}" h="$(h % 12)" + [ "$h" != "$time" ] && m="${time#*:}" || m=0 + elif printf %s "$time" | grep -xEq '(0?[1-9]|1[012])(:[0-5][0-9])? ?(pm|PM)\.?'; then + time="${time%?[aA][mM]}" h="${time%:*}" h="$(h % 12 + 12)" + [ "$h" != "$time" ] && m="${time#*:}" || m=0 + elif printf %s "$time" | grep -xEq '(0?[0-9]|1[0-9]|2[0-3]):[0-5][0-9]'; then + time="${time%?[aA][mM]}" h="${time%:*}" m="${time#*:}" + else + return 1 + fi + + printf '%02i:%02i\n' "${h#0}" "${m#0}" + return 0 +} + +while [ $# -gt 0 ]; do case $1 in + --from|from|--start|start) + if isdate "$2" && istime "$3" ; then + start_date="$(isdate "$2" )" start_time="$(istime "$3")" + shift 3 + elif isdate "${2%% *}" && istime "${2#* }" ; then + start_date="$(isdate "${2%% *}" )" start_time="$(istime "${2#* }")" + shift 2 + elif isdate "$2" ; then + start_date="$(isdate "$2")" start_time="00:00" + shift 2 + else + error_msg="Event start should be \"YYYY-MM-DD\" or \"YYYY-MM-DD hh:mm\"" + shift 1 + fi >/dev/null + ;; + --to|to|--end|end) + if isdate "$2" && istime "$3"; then + end_date="$(isdate "$2")" end_time="$(istime "$3")" + shift 3 + elif isdate "${2%% *}" && istime "${2#* }"; then + end_date="$(isdate "${2%% *}")" end_time="$(istime "${2#* }")" + shift 2 + elif isdate "$2"; then + end_date="$(isdate "$2")" end_time="23:59" + shift 2 + elif istime "$2"; then + end_time="$(istime "$2")" + shift 2 + else + error_msg="Event end should be \"YYYY-MM-DD\" or \"YYYY-MM-DD hh:mm\" or \"hh:mm\"" + shift 1 + fi >/dev/null + ;; + --repeat|--recur|--recurrence|--every|every) + if expr "$2" : '^[0-9]\+$' && + expr "$3" : '^\(days\|nights\|weeks\|months\|years\|weekday\)$'; then + rec_freq="$2" rec_int="$3" + shift 3 + elif expr "$2" : '^[0-9]\+ \+\(days\|nights\|weeks\|months\|years\|weekday\)$'; then + rec_freq="${2%% *}" rec_int="${2##* }" + shift 2 + elif expr "$2" : '^\(day\|daily\|night\|nightly\|week\|weekly\|month\|monthly\|year\|yearly\|annually\)$'; then + rec_freq="1" rec_int="$2" + shift 2 + elif expr "$2" : '^last weekday$'; then + rec_freq="-1" rec_int="weekday" + shift 2 + elif expr "$2 $3" : '^last weekday$'; then + rec_freq="-1" rec_int="weekday" + shift 3 + elif expr "$2" : '^\(biweekly\|bimonthly\)$'; then + rec_freq="2" rec_int="$2" + shift 2 + else + error_msg="Recurrence should be \"N days|weeks|months|years\" or \"N|last weekday\"" + shift 1 + fi >/dev/null + ;; + --until|until) + if isdate $2; then + rec_end="$(isdate "$2")" + shift 2 + else + error_msg="Recurrence end should be \"YYYY-MM-DD\"" + shift 1 + fi >/dev/null + ;; + --title) + title="$2" + shift 2 + ;; + *) shift 1;; +esac; done + +if [ ! "$end_time" ]; then + end_time="23:59" +fi + +if [ ! "$end_date" -a "$end_time" -a "$start_time" ]; then + if [ "$((${end_time%:*} * 60 + ${end_time#*:}))" -gt "$((${start_time%:*} * 60 + ${start_time#*:}))" ]; then + end_date="$start_date" + else + end_date="$(date -d "@$(($(date -d "$start_date" +%s) + 86400))" +%F)" + fi +fi + +if [ ! "$start_date" ]; then + error_msg="Event needs start date, e.g. --start \"YYYY-MM-DD\"" +fi + +if [ ! "$title" ]; then + error_msg="Event needs title, e.g. --title \"Event Name\"" +fi + +if [ "$error_msg" ]; then + _ "$error_msg" + exit 1 +fi + +case $rec_int in + day|daily|days|night|nightly|nights) + rec_int="day";; + week|weeks|weekly|biweekly) + rec_int="week";; + month|monthly|months|bimonthly) + rec_int="month";; + year|yearly|years|annually) + rec_int="year";; +esac + +if [ "$rec_end" ]; then + rec_end="$(date -d "$rec_end" +%s)" +fi + +if [ -s './#events' ]; then + t1="$(stat -c %Y './#page.md')" + read t2 junk <"./#events" + if [ "$t1" -ge "$t2" ]; then + truncate -s 0 "./#events" + fi +fi + +printf '%i %i %i %i %s %i\n' \ + "$_DATE" "$(date -d "$start_date $start_time" +%s)" "$(date -d "$end_date $end_time" +%s)" \ + "${rec_freq:-0}" "${rec_int:-\\}" "${rec_end:--1}" \ + >>'./#events' + +start="$(date -d "$start_date $start_time" +%s)" + end="$(date -d "$end_date $end_time" +%s)" + +if [ $_DATE -le $end ]; then + nstart="$start" nend="$end" +fi + +[ $_DATE -gt $end ] && case $rec_int in + day) + nend=$(( rec_freq * 86400 - (_DATE - end) % (rec_freq * 86400) + _DATE )) + nstart=$(( start - end + nend)) + ;; + week) + nend=$(( rec_freq * 604800 - (_DATE - end) % (rec_freq * 604800) + _DATE )) + nstart=$(( start - end + nend)) + ;; + month) + { read _y _m _d; read y m d; } <<-EOF + $(date -d @$_DATE +"%Y %_m %_d" + date -d @$start +"%Y %_m %_d" + ) + EOF + _m=$((_y * 12 + _m)) m=$((y * 12 + m)) + while :; do + mod=$(( (_m - m) % rec_freq )); [ $mod -eq 0 ] && mod="$rec_freq"; + m=$(( rec_freq - mod + _m )) + y=$((m / 12)) m=$((m % 12)); [ $m -eq 0 ] && y=$((y - 1)) m=12; + nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")" + isdate "$nstart" >/dev/null && [ $(date -d "$nstart" +%s) -ge $_DATE ] && break + debug loop + m=$((y * 12 + m)) _m="$((_m + rec_freq))" + done + nstart="$(date -d "$nstart $start_time" +%s)" + nend="$((end - start + nstart))" + ;; + year) + ;; + '') + nstart="$start" nend="$end" + ;; +esac + +"$_EXEC/cgilite/html-sh.sed" <<-EOF + [div .macro .event + [label . $(HTML "$title")] + [dl + [dt $(_ Start:)][dd $(date -d @$nstart +"%F %T")] + [dt $(_ End:)][dd $(date -d @$nend +"%F %T")] + ] + ] +EOF + +# uid="$(timeid)" +# tzid="$(cat /etc/timezone || printf 'UTC')" +# +# cat >>"#events.ics" <<-EOF +# BEGIN:VCALENDAR +# VERSION:2.0 +# PRODID:ShellWiki Event Macro +# BEGIN:VEVENT +# UID:$uid@$(HEADER Host) +# DTSTAMP:TZID=${tzid}:$(date +%Y%m%dT%H%M%S) +# DTSTART:TZID=${tzid}:$(date +%Y%m%dT%H%M%S -d "$start_date $start_time") +# DURATION: +# RRULE:FREQ=$ec_freq;INTERVAL=$rec_int;UNTIL=$(date +%Y%m%dT000000Z -d "$rec_end") +# SUMMARY: +# COMMENT: +# END:VEVENT +# END:VCARD +# EOF -- 2.39.2