]> git.plutz.net Git - shellwiki/blob - macros/event
avoid localising time records
[shellwiki] / macros / event
1 #!/bin/sh
2
3 . $_EXEC/cgilite/cgilite.sh
4 . $_EXEC/cgilite/storage.sh
5 . $_EXEC/datetime.sh
6
7 _(){ printf %s\\n "$*"; }
8 [ "${LANGUAGE}" -a -r "${_EXEC}/l10n/${LANGUAGE}.sh" ] && . "${_EXEC}/l10n/${LANGUAGE}.sh"
9
10 start_date= start_time= end_date= end_time=
11 rec_freq= rec_int= error_msg= rec_end=
12 title=
13 start= end= nstart= nend=
14
15 while [ $# -gt 0 ]; do case $1 in
16   --from|from|--start|start)
17     if   isdate "$2" && istime "$3" ; then
18       start_date="$(isdate "$2" )" start_time="$(istime "$3")"
19       shift 3
20     elif isdate "${2%% *}" && istime "${2#* }" ; then
21       start_date="$(isdate "${2%% *}" )" start_time="$(istime "${2#* }")"
22       shift 2
23     elif isdate "$2" ; then
24       start_date="$(isdate "$2")" start_time="00:00"
25       shift 2
26     else
27       error_msg="Event start should be \"YYYY-MM-DD\" or \"YYYY-MM-DD hh:mm\""
28       shift 1
29     fi >/dev/null
30     ;;
31   --to|to|--end|end)
32     if   isdate "$2" && istime "$3"; then
33       end_date="$(isdate "$2")" end_time="$(istime "$3")"
34       shift 3
35     elif isdate "${2%% *}" && istime "${2#* }"; then
36       end_date="$(isdate "${2%% *}")" end_time="$(istime "${2#* }")"
37       shift 2
38     elif isdate "$2"; then
39       end_date="$(isdate "$2")" end_time="23:59"
40       shift 2
41     elif istime "$2"; then
42       end_time="$(istime "$2")"
43       shift 2
44     else
45       error_msg="Event end should be \"YYYY-MM-DD\" or \"YYYY-MM-DD hh:mm\" or \"hh:mm\""
46       shift 1
47     fi >/dev/null
48     ;;
49   --repeat|--recur|--recurrence|--every|every)
50     if expr "$2" : '^[0-9]\+$' &&
51        expr "$3" : '^\(days\|nights\|weeks\|months\|years\|weekday\)$'; then
52       rec_freq="$2" rec_int="$3"
53       shift 3
54     elif expr "$2" : '^[0-9]\+ \+\(days\|nights\|weeks\|months\|years\|weekday\)$'; then
55       rec_freq="${2%% *}" rec_int="${2##* }"
56       shift 2
57     elif expr "$2" : '^\(day\|daily\|night\|nightly\|week\|weekly\|month\|monthly\|year\|yearly\|annually\)$'; then
58       rec_freq="1" rec_int="$2"
59       shift 2
60     elif expr "$2" : '^last weekday$'; then
61       rec_freq="-1" rec_int="weekday"
62       shift 2
63     elif expr "$2 $3" : '^last weekday$'; then
64       rec_freq="-1" rec_int="weekday"
65       shift 3
66     elif expr "$2" : '^\(biweekly\|bimonthly\)$'; then
67       rec_freq="2" rec_int="$2"
68       shift 2
69     else
70       error_msg="Recurrence should be \"N days|weeks|months|years\" or \"N|last weekday\""
71       shift 1
72     fi >/dev/null
73     ;;
74   --until|until)
75     if isdate $2; then
76       rec_end="$(isdate "$2")"
77       shift 2
78     else
79       error_msg="Recurrence end should be \"YYYY-MM-DD\""
80       shift 1
81     fi >/dev/null
82     ;;
83   --title)
84     title="$2"
85     shift 2
86     ;;
87   *) shift 1;;
88 esac; done
89
90 if [ ! "$end_time" ]; then
91   end_time="23:59"
92 fi
93
94 if [ ! "$end_date" -a "$end_time" -a "$start_time" ]; then
95   if [ "$((${end_time%:*} * 60 + ${end_time#*:}))" -gt "$((${start_time%:*} * 60 + ${start_time#*:}))" ]; then
96     end_date="$start_date"
97   else
98     end_date="$(date -ud "@$(($(date -ud "$start_date" +%s) + 86400))" +%F)"
99   fi
100 fi
101
102 if [ ! "$start_date" ]; then
103   error_msg="Event needs start date, e.g. --start \"YYYY-MM-DD\""
104 fi
105
106 if [ ! "$title" ]; then
107   error_msg="Event needs title, e.g. --title \"Event Name\""
108 fi
109
110 if [ "$error_msg" ]; then
111   _ "$error_msg"
112   exit 1
113 fi
114
115 case $rec_int in
116   day|daily|days|night|nightly|nights)
117     rec_int="day";;
118   week|weeks|weekly|biweekly)
119     rec_int="week";;
120   month|monthly|months|bimonthly)
121     rec_int="month";;
122   year|yearly|years|annually)
123     rec_int="year";;
124 esac
125
126 [ "$rec_end" ] && rec_end="$(date -ud "$rec_end" +%s)" \
127
128 if LOCK './#events'; then
129   sed -i "/^${_DATE}    /!d" './#events'
130   evid="$(wc -l <'./#events' || printf 0)"
131   printf '%i    %i      %i      %i      %s      %i      %s      %s\n' \
132     "$_DATE" "$(date -ud "$start_date $start_time" +%s)" "$(date -ud "$end_date $end_time" +%s)" \
133     "${rec_freq:-0}" "${rec_int:-\\}" "${rec_end:--1}" "$(STRING "${title}")" "$(STRING "${PATH_INFO}#event${evid}")" \
134     >>'./#events'
135   RELEASE './#events'
136 fi
137
138 start="$(date -ud "$start_date $start_time" +%s)"
139   end="$(date -ud "$end_date $end_time" +%s)"
140
141 if [ $_DATE -le $end ]; then
142   nstart="$start" nend="$end"
143 fi
144
145 [ $_DATE -gt $end ] && case $rec_int in
146   day)
147     nend=$(( rec_freq * 86400 - (_DATE - end) % (rec_freq * 86400) + _DATE ))
148     nstart=$(( start - end + nend))
149     ;;
150   week)
151     nend=$(( rec_freq * 604800 - (_DATE - end) % (rec_freq * 604800) + _DATE ))
152     nstart=$(( start - end + nend))
153     ;;
154   month)
155     { read _y _m _d; read y m d; } <<-EOF
156         $(date -ud @$_DATE +"%Y %_m %_d"
157           date -ud @$start +"%Y %_m %_d"
158         )
159         EOF
160     _m=$((_y * 12 + _m)) m=$((y * 12 + m))
161     while :; do
162       # mod=$(( (_m - m) % rec_freq )); [ $mod -eq 0 ] && mod="$rec_freq";
163       m=$(( rec_freq - ((_m - m - 1) % rec_freq + 1) + _m ))
164       # y=$(((m - 1) / 12)) m=$(((m - 1) % 12 + 1)); # [ $m -eq 0 ] && y=$((y - 1)) m=12;
165       nstart="$(printf '%04i-%02i-%02i' "$(( (m - 1) / 12 ))" "$(( (m - 1) % 12 + 1 ))" "$d")"
166       if isdate "$nstart" && [ "$(date -ud "$nstart" +%s)" -ge "$_DATE" ]; then
167         break
168       fi >/dev/null
169       # m=$((y * 12 + m))
170       _m="$((_m + rec_freq))"
171     done
172     nstart="$(date -ud "$nstart $start_time" +%s)"
173       nend="$((end - start + nstart))"
174     ;;
175   year)
176     { read _y _m _d; read y m d; } <<-EOF
177         $(date -ud @$_DATE +"%Y %_m %_d"
178           date -ud @$start +"%Y %_m %_d"
179         )
180         EOF
181     while :; do
182       # mod=$(( ( _y - y ) % rec_freq )); [ $mod -eq 0 ] && mod="$rec_freq"
183       y=$(( rec_freq - ((_y - y - 1) % rec_freq + 1) + _y ))
184       nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")"
185       if isdate "$nstart" && [ $(date -ud "$nstart" +%s) -ge $_DATE ]; then
186         break
187       fi >/dev/null
188       _y="$((_y + rec_freq))"
189     done
190     nstart="$(date -ud "$nstart $start_time" +%s)"
191       nend="$((end - start + nstart))"
192     ;;
193   '')
194     nstart="$start" nend="$end"
195     ;;
196 esac
197
198 if [ "$nstart" -gt "$rec_end" ] 2>/dev/null; then
199   nstart="$start" nend="$end"
200 fi
201
202 "$_EXEC/cgilite/html-sh.sed" <<-EOF
203   [div .macro .event #event${evid}
204     [label . $(HTML "$title")]
205     [dl
206       [dt $(_ Start:)][dd $(date -ud @$nstart +"%F %T")]
207       [dt   $(_ End:)][dd $(date -ud @$nend +"%F %T")]
208       [dt $(_ Until:)][dd $(date -ud @$rec_end +"%F %T")]
209     ]
210   ]
211 EOF
212
213 # uid="$(timeid)"
214 # tzid="$(cat /etc/timezone || printf 'UTC')"
215
216 # cat >>"#events.ics" <<-EOF
217 # BEGIN:VCALENDAR
218 # VERSION:2.0
219 # PRODID:ShellWiki Event Macro
220 # BEGIN:VEVENT
221 # UID:$uid@$(HEADER Host)
222 # DTSTAMP:TZID=${tzid}:$(date -u +%Y%m%dT%H%M%S)
223 # DTSTART:TZID=${tzid}:$(date -u +%Y%m%dT%H%M%S -d "$start_date $start_time")
224 # DURATION:
225 # RRULE:FREQ=$ec_freq;INTERVAL=$rec_int;UNTIL=$(date -u +%Y%m%dT000000Z -d "$rec_end")
226 # SUMMARY:
227 # COMMENT:
228 # END:VEVENT
229 # END:VCARD
230 # EOF