]> git.plutz.net Git - shellwiki/commitdiff
event macro stubs
authorPaul Hänsch <paul@plutz.net>
Fri, 17 Nov 2023 10:44:26 +0000 (11:44 +0100)
committerPaul Hänsch <paul@plutz.net>
Fri, 17 Nov 2023 10:44:26 +0000 (11:44 +0100)
macros/event [new file with mode: 0755]

diff --git a/macros/event b/macros/event
new file mode 100755 (executable)
index 0000000..2bf3b05
--- /dev/null
@@ -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