4 # Copyright 2024 Paul Hänsch
6 # Permission to use, copy, modify, and/or distribute this software for any
7 # purpose with or without fee is hereby granted, provided that the above
8 # copyright notice and this permission notice appear in all copies.
10 # THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 # SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
16 # IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 . "$_EXEC/cgilite/cgilite.sh"
22 . "$_EXEC/datetime.sh"
24 tags='' ntags='' dir='' depth='' glob_system_pages=false
25 label='' labeltype='' altlabel='' cnt=0
28 while [ $# -gt 0 ]; do case $1 in
29 --system) glob_system_pages=true; shift 1;;
30 --depth) depth="$2" shift 2;;
31 \#*) tags="${tags}${tags:+ }${1###}"; shift 1;;
32 \!*) ntags="${ntags}${ntags:+ }${1##!}"; shift 1;;
33 --date|--from) fromdate="$2"; shift 2;;
34 --weekstart|--ws|-ws) ws="$2"; shift 2;;
36 *) if [ ! "$dir" ]; then
38 set -- "$@" "$1"; shift 1;
39 elif [ ! "$depth" ]; then
42 set -- "$@" "$1"; shift 1;
46 [ "$*" ] || set -- "."
47 [ "$depth" -ge 0 -o "$depth" -le 0 ] 2>&- || depth=0
50 $(isdate "$fromdate" \
51 && date -ud "$fromdate" +"%Y %m %d" \
52 || date -u +"%Y %m %d"
63 # Recurrence Expansion
64 # read recurring event specifications and expand them to a list of
65 # single events within the specified time frame
67 local dstart="$1" dend="$2"
68 local junk1 start end rrfreq rrint rrend evtitle evlink junk2
70 while read -r junk1 start end rrfreq rrint rrend evtitle evlink junk2; do
71 [ ! "$start" ] && continue # empty line
72 [ "$rrend" -eq -1 ] && rrend=9999999999
74 if [ "$start" -lt "$dend" ] &&
75 [ "$end" -gt "$dstart" -o "$rrend" -gt "$dstart" ]; then
82 [ "$rrfreq" -ge 0 ] && rrex_weekday \
86 printf '%i %i %s %s\n' "$start" "$end" "$evtitle" "$evlink"
94 # helper for rrexpand daily/N-day expansion
97 nend=$(( rrfreq * 86400 - (dstart - end) % (rrfreq * 86400) + dstart ))
98 nstart=$(( start - end + nend))
99 while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do
100 [ "$nstart" -ge "$start" ] \
101 && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
102 nstart="$((nstart + rrfreq * 86400))"
103 nend="$((nstart - start + end))"
108 # helper for rrexpand weekly/N-week expansion
111 nend=$(( 0 * 604800 - (dstart - end) % (rrfreq * 604800) + dstart ))
112 nstart=$(( start - end + nend))
113 while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do
114 [ "$nstart" -ge "$start" -a "$nstart" -ge "$dstart" ] \
115 && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
116 nstart="$((nstart + rrfreq * 7 * 86400))"
117 nend="$((nstart - start + end))"
122 # helper for rrexpand monthly/N-month expansion
125 { read _y _m _d; read y m d start_time; } <<-EOF
126 $(date -ud @$dstart +"%Y %_m %_d"
127 date -ud @$start +"%Y %_m %_d %T"
130 _m=$((_y * 12 + _m)) m=$((y * 12 + m))
132 m=$(( rrfreq - ((_m - m - 1) % rrfreq + 1) + _m ))
133 nstart="$(printf '%04i-%02i-%02i' "$(( (m - 1) / 12 ))" "$(( (m - 1) % 12 + 1 ))" "$d")"
134 if isdate "$nstart" && [ "$(date -ud "$nstart" +%s)" -ge "$dstart" ]; then
137 _m="$((_m + rrfreq))"
139 nstart="$(date -ud "$nstart $start_time" +%s)"
140 nend="$((end - start + nstart))"
141 while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do
142 [ "$nstart" -ge "$start" ] \
143 && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
145 nstart="$(printf '%04i-%02i-%02i' "$(( (m - 1) / 12 ))" "$(( (m - 1) % 12 + 1 ))" "$d")"
146 nstart="$(date -ud "$nstart $start_time" +%s)"
147 nend="$((nstart - start + end))"
152 # helper for rrexpand yearly/N-year expansion
155 { read _y _m _d; read y m d start_time; } <<-EOF
156 $(date -ud @$dstart +"%Y %_m %_d"
157 date -ud @$start +"%Y %_m %_d %T"
161 y=$(( rrfreq - ((_y - y - 1) % rrfreq + 1) + _y ))
162 nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")"
163 if isdate "$nstart" && [ "$(date -ud "$nstart" +%s)" -ge "$dstart" ]; then
166 _y="$((_y + rrfreq))"
168 nstart="$(date -ud "$nstart $start_time" +%s)"
169 nend="$((end - start + nstart))"
170 while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do
171 [ "$nstart" -ge "$start" ] \
172 && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
174 nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")"
175 nstart="$(date -ud "$nstart $start_time" +%s)"
176 nend="$((nstart - start + end))"
181 # helper for rrexpand: Nth weekday of a month (e.g. 2nd tuesday, etc.)
184 nth=$(( ( $(date -ud @$start +%_d) - 1) / 7))
186 nend=$(( 0 * 604800 - (dstart - end) % 604800 + dstart ))
187 nstart=$(( start - end + nend))
189 while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do
190 [ "$nstart" -ge "$start" -a "$nstart" -ge "$dstart" ] \
191 && [ "$(( ( $(date -ud @$nstart +%_d) -1) / 7 ))" -eq "$nth" ] \
192 && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
193 nstart="$((nstart + 7 * 86400))"
194 nend="$((nstart - start + end))"
199 # helper for rrexpand: Nth last weekday of a month (e.g. 2nd last tuesday, etc.)
200 local nstart nend Y m d nth
203 $(date -ud @$start +"%Y %_m %_d")
205 nth=$(( ( $(numdays $Y $m) - d ) / 7))
207 nend=$(( 0 * 604800 - (dstart - end) % 604800 + dstart ))
208 nstart=$(( start - end + nend))
210 while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do
212 $(date -ud @$nstart +"%Y %_m %_d")
214 [ "$nstart" -ge "$start" -a "$nstart" -ge "$dstart" ] \
215 && [ "$(( ( $(numdays $Y $m) - d ) / 7 ))" -eq "$nth" ] \
216 && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
217 nstart="$((nstart + 7 * 86400))"
218 nend="$((nstart - start + end))"
224 page_glob "$dir" "$depth"
227 | while read -r page; do
228 pagedir="$(page_abs "$page")"
229 if [ -f "$_DATA/pages/${pagedir}/#events" ] \
230 && acl_read "$pagedir" \
231 && has_tags "$pagedir" $tags \
232 && ! has_tag "$pagedir" $ntags
234 cat "$_DATA/pages/${pagedir}/#events"
240 # Print list view for upcoming events
241 local lday='' events sdate=$(date -ud "${DY}-${DM}-${DD}" +%s)
244 printf %s\\n "$events" \
245 | rrexpand "$sdate" "$((sdate + 42 * 86400))" \
249 printf '<ul class="macro calendar cal_list">\n'
250 printf '%s\n' "${events}" \
251 | while read start end name link; do
252 day="$((start / 86400))"
253 if [ "$day" != "$lday" ]; then
254 [ "$lday" ] && printf '</ul></li>'
255 date -ud "@$start" +'<li><label>%A, %F</label><ul class="day">'
258 printf '<li>%s - <a href="%s">%s</a></li>' \
259 "$(date -ud "@$start" +"%H:%M")" "$(URL "${link%%#*}")#$(URL "${link#*#}")" "$(HTML "${name}")"
261 printf '</ul></li></ul>'
265 local ws events calmonth
266 local iday idow mname dcnt dow dcal start end title link n
268 calmonth="$(GET calmonth || printf %i "$((DY * 12 + DM))")"
269 DY="$(( (calmonth - 1) / 12 ))"
270 DM="$(( (calmonth - 1) % 12 + 1 ))"
272 read -r iday idow mname <<-EOF
273 $(date -ud "${DY}-${DM}-01" +"%s %u %B")
275 dcnt=$((iday - idow * 86400 + ws * 86400))
277 dcal="$(date -ud @"$dcnt" +%d)"
279 printf %s\\n "$events" \
280 | rrexpand "$dcnt" "$((dcnt + 42 * 86400))" \
284 printf '<table class="macro calendar cal_month">'
285 printf '<thead><tr><th><a href="%s"><</a></th><th colspan=5>%s</th><th><a href="%s">></a></th></tr><tr>' \
286 "./?calmonth=$((DY * 12 + DM -1))" "$mname" "./?calmonth=$((DY * 12 + DM + 1))"
287 for n in 0 1 2 3 4 5 6; do date -ud @"$((dcnt + n * 86400))" +'<th>%a</th>'; done
288 printf '</tr></thead><tbody>'
290 [ $dow = $ws ] && printf '<tr>'
291 printf '<td><label>%02i</label>' "$dcal"
294 printf %s "${events}${events:+${BR}}" \
295 | while read start end title link; do
296 if [ "$((start / 86400))" -lt "$((dcnt / 86400))" -a "$end" -gt "$dcnt" ]; then
297 printf '<li><a href="%s\#%s">%s</a></li>' \
298 "$(UNSTRING "${link%%#*}" |URL)" \
299 "$(UNSTRING "${link#*#}" |URL)" \
300 "$(UNSTRING "$title" |HTML)"
301 elif [ "$((start / 86400))" -eq "$((dcnt / 86400))" ]; then
302 printf '<li>%s - <a href="%s#%s">%s</a></li>' \
303 "$(date -ud @"$start" +%H:%M)" \
304 "$(UNSTRING "${link%%#*}" |URL)" \
305 "$(UNSTRING "${link#*#}" |URL)" \
306 "$(UNSTRING "$title" |HTML)"
310 [ "$evlist" ] && printf '<ul>%s</ul>' "$evlist"
313 [ $dow = $(( (ws + 6) % 7)) ] && printf '</tr>\n'
315 dcnt=$(( dcnt + 86400 ))
316 dow=$(( (dow + 1) % 7 ))
318 && dcal=$((dcal + 1)) \
319 || dcal=$(date -ud @"$dcnt" +%d)
320 [ $dcnt -gt $((iday + 28 * 86400)) -a $dcal -le 7 -a $dow = $ws ] \
323 printf '</tbody></table>'