cgi_refdata
card="$_GET[\"card\"]"
-debug card: $card
filter="&filter=$_REF[\"filter\"]"
filtertype="&filtertype=$_REF[\"filtertype\"]"
order="&order=$_REF[\"order\"]"
--- /dev/null
+#!/bin/zsh
+
+course="$_GET[\"course\"]"
+
+echo -n "Location: http://$HTTP_HOST/?page=courses&edit=$course\n\n"
--- /dev/null
+#!/bin/zsh
+
+cgi_post
+
+uid=$(dbus-uuidgen)
+course="${uid}.ics"
+
+tzid=$(cat /etc/timezone)
+tstamp=$(TZ="$tzid" date +%Y%m%dT%H%M%S)
+
+tempfile="$_DATA/temp/$course"
+
+cat >"$tempfile" <<EOF
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:Berlin RAW Confetti
+BEGIN:VEVENT
+UID:$uid
+DTSTAMP:TZID=${tzid}:${tstamp}
+DTSTART:
+DURATION:
+RRULE:
+SUMMARY:
+COMMENT:
+END:VEVENT
+END:VCARD
+EOF
+
+echo -n "Location: http://$HTTP_HOST/?page=courses&edit=$course\n\n"
value="$_POST[\"$field\"]"
n=0
while [ -n "$value" ]; do
+ value="$(echo "$value" |sed -r ':a;N;$!ba;s:\n:\\\\n:g;s:\r:\\\\r:g')"
echo "${field}:${value}\r"
value="$_POST[\"$field$n\"]"
n=$(($n + 1))
--- /dev/null
+#!/bin/zsh
+
+cgi_post
+
+course="$_POST[\"course\"]"
+tempfile="temp/$course"
+coursefile="ical/$course"
+
+# DURATION:
+uid="$_POST[\"UID\"]"
+
+tzid=$(cat /etc/timezone)
+tstamp=$(TZ="$tzid" date +%Y%m%dT%H%M%S)
+
+dts_year="$_POST[\"DTSYEAR\"]"
+dts_month="$_POST[\"DTSMONTH\"]"
+dts_day="$_POST[\"DTSDAY\"]"
+[ -n "$_POST[\"DTSDAY0\"]" ] && dts_day="$_POST[\"DTSDAY0\"]"
+dts_hour="$_POST[\"DTSHOUR\"]"
+dts_minute="$_POST[\"DTSMINUTE\"]"
+
+[ -z $dts_year ] && dts_year=$(date +%Y)
+[ -z $dts_month ] && dts_month=$(date +%m)
+[ -z $dts_day ] && dts_day=$(date +%d)
+date -d ${dts_year}-${dts_month}-${dts_day} >/dev/null 2>/dev/null || dts_day="01"
+[ -z $dts_hour ] && dts_hour=$(date +%H)
+[ -z $dts_minute ] && dts_minute=$(date +%M)
+
+dtstart="TZID=${tzid}:${dts_year}${dts_month}${dts_day}T${dts_hour}${dts_minute}00"
+
+rr_int="$_POST[\"RRULE_INTERVAL\"]"
+rr_freq="$_POST[\"RRULE_FREQ\"]"
+rr_limit="$_POST[\"RRULE_LIMIT\"]"
+case "$rr_limit" in
+ ETERN)
+ rrule="FREQ=$rr_freq;INTERVAL=$rr_int"
+ ;;
+ COUNT)
+ t="$_POST[\"RRULE_COUNT\"]"
+ rrule="FREQ=$rr_freq;INTERVAL=$rr_int;COUNT=$t"
+ ;;
+ UNTIL)
+ uy="$_POST[\"RRULE_UYEAR\"]"
+ um="$_POST[\"RRULE_UMONTH\"]"
+ ud="$_POST[\"RRULE_UDAY\"]"
+ rrule="FREQ=$rr_freq;INTERVAL=$rr_int;UNTIL=${uy}${um}${ud}T000000Z"
+ ;;
+esac
+
+echo "BEGIN:VCALENDAR\r" >"$tempfile"
+echo "VERSION:2.0\r" >>"$tempfile"
+echo "PRODID:Berlin RAW Confetti\r" >>"$tempfile"
+echo "BEGIN:VEVENT\r" >>"$tempfile"
+echo "UID:$uid\r" >>"$tempfile"
+echo "DTSTAMP:TZID=${tzid}:${tstamp}\r" >>"$tempfile"
+echo "DTSTART:${dtstart}\r" >>"$tempfile"
+echo "RRULE:${rrule}\r" >>"$tempfile"
+for field in SUMMARY COMMENT; do
+ value="$_POST[\"$field\"]"
+ n=0
+ while [ -n "$value" ]; do
+ value="$(echo "$value" |sed -r ':a;N;$!ba;s:\n:\\\\n:g;s:\r:\\\\r:g')"
+ echo "${field}:${value}\r"
+ value="$_POST[\"$field$n\"]"
+ n=$(($n + 1))
+ done
+done >>"$tempfile"
+
+case "$_POST[\"action\"]" in
+ addfield)
+ echo "$_POST[\"newfield\"]:\r" >>"$tempfile"
+ echo "END:VEVENT\r" >>"$tempfile"
+ echo "END:VCALENDAR\r" >>"$tempfile"
+ echo -n "Location: http://$HTTP_HOST/?page=courses&edit=$course\n\n"
+ ;;
+ update)
+ echo "END:VEVENT\r" >>"$tempfile"
+ echo "END:VCALENDAR\r" >>"$tempfile"
+ mv "$tempfile" "$coursefile"
+ echo -n "Location: http://$HTTP_HOST/?page=courses#$course\n\n"
+ ;;
+ cancel)
+ rm "$tempfile"
+ [ -f "$coursefile" ] \
+ && echo -n "Location: http://$HTTP_HOST/?page=courses#$course\n\n" \
+ || echo -n "Location: http://$HTTP_HOST/?page=courses\n\n"
+ ;;
+ delete)
+ rm "$tempfile" "$coursefile"
+ echo -n "Location: http://$HTTP_HOST/?page=courses\n\n"
+ ;;
+ *)
+ echo "END:VEVENT\r" >>"$tempfile"
+ echo "END:VCALENDAR\r" >>"$tempfile"
+ echo -n "Location: http://$HTTP_HOST/?page=courses&edit=$course\n\n"
+ ;;
+esac
else
_POST["$key"]="$value"
fi
+ #debug "_POST[$key] => $value"
done
}
card="$_GET[\"card\"]"
cat "$_DATA/vcard/$card"
;;
+ ical)
+ echo -n "Content-Type: text/calendar;charset=utf-8\n\n"
+ course="$_GET[\"course\"]"
+ cat "$_DATA/ical/$course"
+ ;;
esac
[ -w "$_DATA" ] && [ -d "$_DATA" ] || die "storage directory must be writable"
# create directories for object storage
-for each in "$_DATA"/{vcard,mappings,courses,cache,temp}; do
+for each in "$_DATA"/{vcard,ical,cache,temp}; do
[ ! -e "$each" ] && mkdir "$each"
[ -w "$each" ] && [ -d "$each" ] || die "storage $each must be a writable directory"
done
;;
course)
;;
- *) ls -1 ${_DATA}/vcard/*vcf
+ *) ls -1 ${_DATA}/vcard/*vcf 2>/dev/null
;;
esac |case "$_GET[\"order\"]" in
firstname)
#!/bin/sh
+listcourses() {
+ case "$_GET[\"filtertype\"]" in
+ *) ls -1 ${_DATA}/ical/*ics 2>/dev/null
+ ;;
+ esac |case "$_GET[\"order\"]" in
+ *)
+ sed -r 's:^.*$:x\t&:'
+ ;;
+ esac |sort |sed -r 's:^.*\t(.*/)([^/]+)$:\2:'
+}
+
+ics_parse() {
+ tr -d '\n' <"$1" |sed -r 's:\r ::g;s:\r:\n:g' |tr -d '\r' \
+ | sed -r 's:^([^;\:]+)(;[^"\:]+|;"[^"]+")*\:(.*)$:key="\1"\nvalue="\3"\ntag=\2:g' \
+ | while read -r line; do
+ case "$line" in
+ key=*) echo -E "$line"
+ ;;
+ value=*) echo -E "$line"
+ ;;
+ tag=*) ot=''
+ echo -E "$line" \
+ | sed -r 's:^tag=::;s:\;([A-Z+_-]+="[^"]+"|[A-Z+_-]+=[^\;]+):\n\1:g;' \
+ | sed -r 's:([A-Z+_-]+)="?(.*)"?:tag\[\1\]="\2":g' \
+ | sed -r '/^ *$/d' \
+ | sort |while read -r tag; do
+ nt="$(echo -E "$tag" |sed -r 's:^tag\[([A-Z+_-]+)\]="(.*)"$:\1:')"
+ nv="$(echo -E "$tag" |sed -r 's:^tag\[([A-Z+_-]+)\]="(.*)"$:\2:')"
+ [ "$nt" = "$ot" ] && vl="$nv,$vl" || vl="$nv"
+ echo -E "tag[$nt]=\"$vl\""
+ ot="$nt"
+ done
+ ;;
+ esac
+ done
+}
+
+view_course() { #Parameter: Calendarfile
+ id="$1"
+ calendarfile="$_DATA/ical/${id}"
+ cachefile="$_DATA/cache/${id}.cache"
+ unset key
+ if [ "$cachefile" -nt "$calendarfile" ]; then
+ cat "$cachefile"
+ else
+ declare -A tags
+ declare -A values
+ ics_parse "$calendarfile" |while read -r line; do
+ declare -A tag
+ case "$line" in
+ value*) eval "$line";;
+ tag*) eval "$line";;
+ key*)
+ if [ -z "$key" ]; then
+ eval "$line"
+ else
+ values[$key]="$value"
+ for t in ${(k)tag}; do
+ tags[${key}_$t]="$tag[$t]"
+ done
+ eval "$line"
+ if [ -n "$values[$key]" ]; then
+ n=0
+ while [ -n "$values[$key$n]" ]; do n=$(($n + 1)); done
+ key=$key$n
+ fi
+ unset value
+ unset tag
+ fi
+ ;;
+ esac
+ done
+ . ${_EXEC}/templates/view_course.sh |tee "$cachefile"
+ fi
+}
+
+edit_course() { #Parameter: Calendarfile
+ id="$1"
+ calendarfile="$_DATA/ical/$id"
+ tempfile="$_DATA/temp/$id"
+ [ -f "$tempfile" ] && calendarfile="$tempfile"
+ unset key
+
+ declare -A tags
+ declare -A values
+ ics_parse "$calendarfile" |while read -r line; do
+ declare -A tag
+ case "$line" in
+ value*) eval "$line";;
+ tag*) eval "$line";;
+ key*)
+ if [ -z "$key" ]; then
+ eval "$line"
+ else
+ [ -n "$value" ] && values[$key]="$value" || values[$key]='\r'
+ for t in ${(k)tag}; do
+ tags[${key}_$t]="$tag[$t]"
+ done
+ eval "$line"
+ if [ -n "$values[$key]" ]; then
+ n=0
+ while [ -n "$values[${key}${n}]" ]; do n=$(($n + 1)); done
+ key=$key$n
+ fi
+ unset value
+ unset tag
+ fi
+ ;;
+ esac
+ done
+ . ${_EXEC}/templates/edit_course.sh
+}
+
case "$1" in
title)
echo "Kurse"
;;
css)
+ . ${_EXEC}/templates/courses.css.sh
;;
body)
+ . ${_EXEC}/templates/text_courses.sh
+ . ${_EXEC}/templates/courses.html.sh
;;
esac
--- /dev/null
+cat <<EOF
+
+.newcourse {
+ display: block;
+ width: 126ex;
+ border-width: 1px;
+ border-style: solid;
+ border-radius: 4px 4px 0 0;
+ margin: 1em auto .25em auto;
+ padding: .25em 2ex .25em 2ex;
+ background: #EFF;
+}
+
+.courselist .course {
+ display: block;
+ width: 130ex;
+ border-style: solid;
+ border-width: 1px;
+ margin: .25em auto;
+ padding: 0;
+ overflow: auto;
+ background: #FFF;
+}
+
+.courselist .course .section {
+ display: inline-block;
+ float:left;
+ width: 25ex;
+ margin: .125em .5ex .5ex .5ex;
+ padding: 0 .2em .2em .2em;
+ background: #EEE;
+}
+
+.courselist .course .dtstart {
+ width: 35ex;
+}
+.courselist .course .dtstart .DTSYEAR{
+ display: inline-block;
+ text-align: center;
+ font-weight: bold;
+ width: 11ex;
+}
+.courselist .course .dtstart .DTSMONTH{
+ display: inline-block;
+ text-align: center;
+ font-weight: bold;
+ width: 18ex;
+}
+.courselist .course .dtstart .DTS{
+ display: inline-block;
+ text-align: center;
+ font-weight: bold;
+ width: 4ex;
+}
+.courselist .course .dtstart .DTSCALHEAD{
+ display: inline-block;
+ font-weight: bold;
+ width: 4ex;
+ margin: .25ex;
+}
+.courselist .course .dtstart .DTSCAL{
+ display: inline-block;
+ width: 4ex;
+ margin: .25ex;
+}
+.courselist .course .dtstart .selected {
+ font-weight: bold;
+}
+.courselist .course .dtstart .DTSTIME{
+ display: inline-block;
+ width: 10ex;
+}
+.courselist .course .dtstart span.DTSTIME{
+ font-weight: bold;
+}
+
+.courselist .course .recur{
+ width: 35ex;
+}
+
+.courselist .course .control {
+ float: right;
+ max-width: 22ex;
+ text-align: right;
+ margin-right: 0;
+ background: #EEF;
+}
+.courselist .course .control .item {
+ color: #008;
+ margin-top: .2em;
+ margin-right: 1ex;
+}
+.courselist .course .control a.item {
+ min-width: 10ex;
+ border-style: solid double solid solid;
+ border-width: 1px 3px 1px 1px;
+ border-color: #000;
+ padding: .1em 1ex;
+ background: #FFF;
+}
+.courselist .course .control a.item:hover{
+ border-width: 1px 1px 1px 1px;
+}
+
+.courselist .course .section .sectitle {
+ display: block;
+ font-weight: bold;
+ margin: .2em .2em .2em .2em;
+}
+
+.courselist .course .section .item {
+ display: block;
+ max-width: 25ex;
+ word-wrap: break-word;
+}
+.courselist .course .section input[type="text"] {
+ width: 24ex;
+}
+
+.courselist .course .section textarea.COMMENT {
+ width: 24ex;
+ min-height: 6em;
+}
+
+EOF
+
+# vi:set filetype=css:
--- /dev/null
+
+edit="$_GET[\"edit\"]"
+
+cat <<EOF
+<div class="newcourse">
+ <form action="?action=new_course" method="POST">
+ <button type="submit">$(l10n newcourse)</button>
+ </form>
+</div>
+
+<div class="courselist">
+$(
+[ -f "ical/$edit" -o -f "temp/$edit" ] && edit_course "$edit"
+if [ "$?" = 0 ]; then
+ listcourses |grep -v "$edit"
+else
+ listcourses
+fi |while read card; do
+ view_course "$card"
+done
+)
+</div>
+EOF
+
+# vi:set filetype=html:
n_pre="$(echo "$values[N]" |sed -rn 's:^([^;]*;){3} *([^;]*).*$:\2:p')"
n_post="$(echo "$values[N]" |sed -rn 's:^([^;]*;){4} *([^;]*)*$:\2:p')"
-declare -A SUP_FIELDS
SUP_FIELDS=(N NICKNAME GENDER BDAY EMAIL TEL IMPP ADR URL NOTE)
[ -z "$values[UID]" ] && values[UID]="$(dbus-uuidgen)"
--- /dev/null
+
+SUP_FIELDS=(SUMMARY COMMENT)
+[ -z "$values[UID]" ] && values[UID]="$(dbus-uuidgen)"
+
+dtstart="$values[DTSTART]"
+[ -z "$dtstart" ] && dtstart=$(date +%Y%m%dT%H%M%S)
+
+echo "$dtstart" |case "$dtstart" in
+ *Z)
+ sed -rn 's:^([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})Z$:\1-\2-\3 \4\:\5\:\6 UTC:p'
+ ;;
+ TZID*)
+ sed -rn 's:^TZID=(.+)\:([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})$:TZ="\1" \2-\3-\4 \5\:\6\:\7:p'
+ ;;
+ *)
+ sed -rn 's:^([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})$:\1-\2-\3 \4\:\5\:\6:p'
+ ;;
+esac |read dts_date
+
+dts_year=$(date -d "$dts_date" +%Y)
+dts_month=$(date -d "$dts_date" +%m)
+dts_dom=$(date -d "$dts_date" +%d)
+dts_dow=$(date -d "$dts_date" +%u)
+dts_weekday=$(date -d "$dts_date" +%A)
+dts_hour=$(date -d "$dts_date" +%H)
+dts_min=$(date -d "$dts_date" +%M)
+dts_sec=$(date -d "$dts_date" +%S)
+
+rrule="$values[RRULE]"
+rr_int="$(echo $rrule |sed -rn 's:^.*INTERVAL=([0-9]+)(;.*)?$:\1:p')"
+rr_count="$(echo $rrule |sed -rn 's:^.*COUNT=([0-9]+)(;.*)?$:\1:p')"
+rr_freq="$(echo $rrule |sed -rn 's:^.*FREQ=(YEARLY|MONTHLY|WEEKLY|DAILY)(;.*)?$:\1:p')"
+rr_uyear="$(echo $rrule |sed -rn 's:^.*UNTIL=([0-9]{4})([0-9]{2})([0-9]{2})T[0-9]{6}Z(;.*)?$:\1:p')"
+rr_umonth="$(echo $rrule |sed -rn 's:^.*UNTIL=([0-9]{4})([0-9]{2})([0-9]{2})T[0-9]{6}Z(;.*)?$:\2:p')"
+rr_uday="$(echo $rrule |sed -rn 's:^.*UNTIL=([0-9]{4})([0-9]{2})([0-9]{2})T[0-9]{6}Z(;.*)?$:\3:p')"
+if [ -n "$rr_count" ]; then
+ rr_limit=COUNT
+elif [ -n "$rr_uyear" ]; then
+ rr_limit=UNTIL
+else
+ rr_limit=ETERN
+fi
+
+echo '<div id="'${id}'" class="course">'
+echo '<form action="/?action=update_course" method="POST">'
+echo '<input type="hidden" name="course" value="'${id}'"/>'
+echo ' <div class="section basic">'
+echo ' <span class="sectitle">'$(l10n SUMMARY)'</span>'
+echo ' <input type="text" class="item SUMMARY" name="SUMMARY" value="'$values[SUMMARY]'" />'
+echo ' <span class="sectitle">'$(l10n COMMENT)'</span>'
+for n in COMMENT COMMENT{0..10}; do [ -n "$values[$n]" ] &&\
+ echo ' <textarea class="item COMMENT" name="COMMENT">'$values[$n]'</textarea>'
+done
+echo ' </div>'
+
+echo ' <div class="section dtstart">'
+echo ' <span class="sectitle">'$(l10n DTSTART)'</span>'
+echo ' <select class="DTSYEAR" name="DTSYEAR" onchange="this.form.submit();">'
+for y in {$(($dts_year - 50))..$(($dts_year + 50))}; do
+ echo ' <option value="'$y'" '$([ "$y" -eq "$dts_year" ] && echo 'selected="selected"')'>'$y'</option>'
+done
+echo ' </select>'
+echo ' <select class="DTSMONTH" name="DTSMONTH" onchange="this.form.submit();">'
+for m in {01..12}; do
+ echo ' <option value="'$m'" '$([ "$m" -eq "$dts_month" ] && echo 'selected="selected"')'>'$(date -d ${dts_year}-${m}-1 +%B)'</option>'
+done
+echo ' </select>'
+echo ' <button class="DTS" type="submit" name="DTS" value="update">'$(l10n edit_dtscal)'</button>'
+for wd in mon tue wed thu fri sat sun; do
+ echo ' <span class="DTSCALHEAD">'$(date -d $wd +%a)'</span>'
+done
+fdom=$(date -d ${dts_year}-${dts_month}-1 +%u)
+while [ "$fdom" -gt 1 ]; do
+ echo ' <span class="DTSCAL"></span>'
+ fdom=$(($fdom - 1))
+done
+echo '<input type="hidden" name="DTSDAY" value="'$dts_dom'">'
+cnt=$(date -d ${dts_year}-${dts_month}-1 +%s)
+while [ "$(date -d @$cnt +%m)" = "$dts_month" ]; do
+ dn=$(date -d @$cnt +%d)
+ echo ' <button class="DTSCAL '$( [ $dn = $dts_dom ] && echo selected)'" type="submit" name="DTSDAY" value="'$dn'">'$dn'</button>'
+ cnt=$(($cnt + 86400))
+done
+echo ' <br />'
+echo ' <span class="DTSTIME">'$(l10n time)':</span>'
+echo ' <select class="DTSTIME" name="DTSHOUR">'
+for h in {00..23}; do
+ echo ' <option value="'$h'" '$([ "$h" -eq "$dts_hour" ] && echo 'selected="selected"')'>'$h'</option>'
+done
+echo ' </select>:<select class="DTSTIME" name="DTSMINUTE">'
+for m in {00..59}; do
+ echo ' <option value="'$m'" '$([ "$m" -eq "$dts_min" ] && echo 'selected="selected"')'>'$m'</option>'
+done
+echo ' </select>'
+echo ' </div>'
+
+echo ' <div class="section recur">'
+echo ' <span class="sectitle">'$(l10n RRULE)'</span>'
+echo ' <span class="text">'$(l10n t_every)'</span>'
+echo ' <select class="RRULE INTERVAL" name="RRULE_INTERVAL">'
+for i in {1..365}; do
+ echo ' <option value="'$i'" '$([ "$i" = "$rr_int" ] && echo 'selected="selected"')'>'$i'</option>'
+done
+echo ' </select>'
+echo ' <select class="RRULE FREQ" name="RRULE_FREQ">'
+for f in DAILY WEEKLY MONTHLY YEARLY; do
+ echo ' <option value="'$f'" '$([ "$f" = "$rr_freq" ] && echo 'selected="selected"')'>'$(l10n $f)'</option>'
+done
+echo ' </select><br/>'
+echo ' <input type="radio" name="RRULE_LIMIT" value="ETERN" '$([ "$rr_limit" = ETERN ] && echo 'checked="checked"')'>'$(l10n t_eternal)'</input><br/>'
+echo ' <input type="radio" name="RRULE_LIMIT" value="COUNT" '$([ "$rr_limit" = COUNT ] && echo 'checked="checked"')'></input>'
+echo ' <select class="RRULE COUNT" name="RRULE_COUNT">'
+for t in {1..365}; do
+ echo ' <option value="'$t'" '$([ "$t" = "$rr_count" ] && echo 'selected="selected"')'>'$t'</option>'
+done
+echo ' </select><span class="text">'$(l10n t_times)'</span><br/>'
+echo ' <input type="radio" name="RRULE_LIMIT" value="UNTIL" '$([ "$rr_limit" = UNTIL ] && echo 'checked="checked"')'>'$(l10n t_until)'</input>'
+echo ' <select class="RRULE UYEAR" name="RRULE_UYEAR">'
+for uy in {${dts_year}..$(($dts_year + 50))}; do
+ echo ' <option value="'$uy'" '$([ "$uy" = "$rr_uyear" ] && echo 'selected="selected"')'>'$uy'</option>'
+done
+echo ' </select>'
+echo ' <select class="RRULE UMONTH" name="RRULE_UMONTH">'
+for um in {01..12}; do
+ echo ' <option value="'$um'" '$([ "$um" = "$rr_umonth" ] && echo 'selected="selected"')'>'$(date -d 2000-${um}-1 +%B)'</option>'
+done
+echo ' </select>'
+echo ' <select class="RRULE UDAY" name="RRULE_UDAY">'
+for ud in {01..31}; do
+ echo ' <option value="'$ud'" '$([ "$ud" = "$rr_uday" ] && echo 'selected="selected"')'>'$ud'</option>'
+done
+echo ' </select>'
+echo ' </div>'
+
+echo ' <div class="section control">'
+echo ' <button class="item control" type="submit" name="action" value="addfield">'$(l10n edit_addfield)'</button>'
+echo ' <select class="item control" name="newfield">'
+echo ' <option value="" disabled="disabled" selected="selected">'$(l10n edit_addfieldtext)'</option>'
+ for f in $SUP_FIELDS; do echo "<option value=\"$f\">$(l10n $f)</option>"; done
+echo ' </select>'
+echo ' <button class="item control" type="submit" name="action" value="update">'$(l10n edit_update)'</button>'
+echo ' <button class="item control" type="submit" name="action" value="delete">'$(l10n edit_delete)'</button>'
+echo ' <button class="item control" type="submit" name="action" value="cancel">'$(l10n edit_cancel)'</button>'
+echo ' </div>'
+echo '<input type="hidden" name="UID" value="'$values["UID"]'"/>'
+echo '</form>'
+echo '</div>'
+
--- /dev/null
+declare -A item_name
+
+item_name[SUMMARY]="Bezeichnung"
+item_name[COMMENT]="Kommentar"
+item_name[DTSTART]="Beginn"
+item_name[DURATION]="Dauer"
+item_name[RRULE]="Regelmäßigkeit"
+
+item_name[DAILY]="Tage"
+item_name[WEEKLY]="Wochen"
+item_name[MONTHLY]="Monate"
+item_name[YEARLY]="Jahre"
+
+item_name[sDAILY]="Täglich"
+item_name[sWEEKLY]="Wöchentlich"
+item_name[sMONTHLY]="Monatlich"
+item_name[sYEARLY]="Jährlich"
+
+item_name[newcourse]="Neuen Eintrag anlegen"
+item_name[time]="Uhrzeit"
+item_name[edit_update]="Daten übernehmen"
+item_name[edit_cancel]="Abbrechen"
+item_name[edit_delete]="Eintrag löschen"
+item_name[edit_addfieldtext]="Neues Feld"
+item_name[edit_addfield]="+"
+item_name[edit_dtscal]="✓"
+
+item_name[t_every]="Alle"
+item_name[t_eternal]="ewig"
+item_name[t_times]="mal"
+item_name[t_until]="Bis"
+item_name[t_oclock]="Uhr"
+
+l10n() {
+ [ -n "$item_name[$1]" ] && echo -n "$item_name[$1]" || echo -n "$1"
+}
+
+dtstart="$values[DTSTART]"
+[ -z "$dtstart" ] && dtstart=$(date +%Y%m%dT%H%M%S)
+
+echo "$dtstart" |case "$dtstart" in
+ *Z)
+ sed -rn 's:^([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})Z$:\1-\2-\3 \4\:\5\:\6 UTC:p'
+ ;;
+ TZID*)
+ sed -rn 's:^TZID=(.+)\:([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})$:TZ="\1" \2-\3-\4 \5\:\6\:\7:p'
+ ;;
+ *)
+ sed -rn 's:^([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})$:\1-\2-\3 \4\:\5\:\6:p'
+ ;;
+esac |read dts_date
+
+dts_year=$(date -d "$dts_date" +%Y)
+dts_month=$(date -d "$dts_date" +%m)
+dts_dom=$(date -d "$dts_date" +%d)
+dts_dow=$(date -d "$dts_date" +%u)
+dts_weekday=$(date -d "$dts_date" +%A)
+dts_hour=$(date -d "$dts_date" +%H)
+dts_min=$(date -d "$dts_date" +%M)
+dts_sec=$(date -d "$dts_date" +%S)
+
+rrule="$values[RRULE]"
+rr_int="$(echo $rrule |sed -rn 's:^.*INTERVAL=([0-9]+)(;.*)?$:\1:p')"
+rr_count="$(echo $rrule |sed -rn 's:^.*COUNT=([0-9]+)(;.*)?$:\1:p')"
+rr_freq="$(echo $rrule |sed -rn 's:^.*FREQ=(YEARLY|MONTHLY|WEEKLY|DAILY)(;.*)?$:\1:p')"
+rr_uyear="$(echo $rrule |sed -rn 's:^.*UNTIL=([0-9]{4})([0-9]{2})([0-9]{2})T[0-9]{6}Z(;.*)?$:\1:p')"
+rr_umonth="$(echo $rrule |sed -rn 's:^.*UNTIL=([0-9]{4})([0-9]{2})([0-9]{2})T[0-9]{6}Z(;.*)?$:\2:p')"
+rr_uday="$(echo $rrule |sed -rn 's:^.*UNTIL=([0-9]{4})([0-9]{2})([0-9]{2})T[0-9]{6}Z(;.*)?$:\3:p')"
+rr_udate="$(echo $rrule |sed -rn 's:^.*UNTIL=([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})Z(;.*)?$:\1-\2-\3 \4\:\5\:\6:p')"
+if [ -n "$rr_count" ]; then
+ rr_limit=COUNT
+elif [ -n "$rr_uyear" ]; then
+ rr_limit=UNTIL
+else
+ rr_limit=ETERN
+fi
+
+echo '<div id="'${id}'" class="course">'
+echo '<form action="/?action=update_course" method="POST">'
+echo '<input type="hidden" name="course" value="'${id}'"/>'
+echo ' <div class="section basic">'
+echo ' <span class="sectitle">'$values[SUMMARY]'</span>'
+echo ' <span class="text">'$(date -d "$dts_date" "+%A %B %d, %Y - %H:%M") $(l10n t_oclock)'</span>'
+[ "$rr_int" -eq 1 ] \
+&& echo '<span class="text">'$(l10n s$rr_freq)'</span>' \
+|| echo '<span class="text">'$(l10n t_every) ${rr_int} $(l10n $rr_freq)'</span>'
+case "$rr_limit" in
+ COUNT)
+ m1=$(echo $rr_freq |sed -r "s:DAILY:day:g;s:WEEKLY:week:g;s:MONTHLY:month:g;s:YEARLY:year:g;")
+ m2=$(($rr_int * $rr_count))
+ echo '<span class="text">'$(l10n t_until) $(date -d "$dts_date + $m2 $m1" "+%A %B %d, %Y - %H:%M")'</span>'
+ ;;
+ UNTIL)
+ echo '<span class="text">'$(l10n t_until) $(date -d "$rr_udate" "+%A %B %d, %Y - %H:%M")'</span>'
+ ;;
+esac
+echo ' </div>'
+
+echo ' <div class="section COMMENT">'
+echo ' <span class="sectitle">'$(l10n COMMENT)'</span>'
+for n in COMMENT COMMENT{0..10}; do [ -n "$values[$n]" ] &&\
+ echo ' <p class="item COMMENT">'$values[$n]'</p>'
+done
+echo ' </div>'
+
+echo ' <div class="section control">'
+echo ' <a class="item control" href="?action=edit_course&course='${id}'">'$(l10n edit)'</a>'
+echo ' <a class="item control" href="?export=ical&course='${id}'">'$(l10n vcf_export)'</a>'
+echo ' </div>'
+echo '<input type="hidden" name="UID" value="'$values["UID"]'"/>'
+echo '</form>'
+echo '</div>'
+