]> git.plutz.net Git - confetti/blob - actions/generate_courselist.sh
improved vcf parser (speed, security)
[confetti] / actions / generate_courselist.sh
1 #!/bin/zsh
2
3 # Copyright 2014, 2016 Paul Hänsch
4 #
5 # This file is part of Confetti.
6
7 # Confetti is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11
12 # Confetti is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU Affero General Public License for more details.
16
17 # You should have received a copy of the GNU Affero General Public License
18 # along with Confetti.  If not, see <http://www.gnu.org/licenses/>. 
19
20 pdflatex="$(where pdflatex |head -n1 || echo false)"
21 course="${_GET[course]}"
22 fromdate="${_GET[fromdate]}"
23 fromdate="$(date -d "$fromdate" +%s)" 2>/dev/null
24 [ -z "$fromdate" ] && fromdate=$(date +%s)
25
26 . ${_EXEC}/pages/courses.sh
27 . ${_EXEC}/pages/cards.sh
28
29 tex_clean() { #in dire need for improvement
30   echo "$*" |tr -d '{&}\\'
31 }
32
33
34 list_attendee() {  #Parameter: Cardfile
35   id="$1"
36   cardfile="$_DATA/vcard/${id}"
37
38   unset key
39   declare -A tags
40   declare -A values
41
42   if [ -r "$cardfile" ]; then
43     vcf_parse "$cardfile" |while read -r line; do
44       declare -A tag
45       case "$line" in
46         value*) eval "$line";;
47         tag*)   eval "$line";;
48         key*)
49           if [ -z "$key" ]; then
50             eval "$line"
51           else
52             values[$key]="$(tex_clean "$value")"
53             for t in ${(k)tag}; do
54               tags[${key}_$t]="$tag[$t]"
55             done
56             eval "$line"
57             if [ -n "$values[$key]" ]; then
58               n=0
59               while [ -n "$values[$key$n]" ]; do n=$(($n + 1)); done
60               key=$key$n
61             fi
62             unset value
63             unset tag
64           fi
65         ;;
66       esac
67     done
68
69     n=$(printf %s "$values[N]" \
70         | sed -rn 's:^([^;]*)(;[^;]*)(;[^;]*)?(;[^;]*)?(;[^;]*)?$:\4 \2 \3 \1 \5:gp' \
71         | sed -r 's:,: :;s:;: :g;s: +: :g;s:^ $::;'
72        )
73     fullname="${n:-${values[FN]:-${values[NICKNAME]}}}"
74
75     tel=''
76     for n in TEL TEL{0..10}; do if (echo "$values[$n]" |grep -Eq '[0-9]'); then
77       [ -n "$tel" ] && tel="$tel\\newline $values[$n]" || tel="$values[$n]"
78     fi; done
79
80     note=''
81     for n in NOTE NOTE{0..10}; do if [ -n "$values[$n]" ]; then
82       [ -n "$note" ] && note="$note\\newline $values[$n]" || note="$values[$n]"
83     fi; done
84     printf '%s & %s & %s & %s\n' "$fullname" "$values[BDAY]" "$tel" "$note" \
85     | sed -r ':X;N;$!bX; s;\n;\\newline ;g'
86   fi
87 }
88
89 get_dates() {  #Parameter: Calendarfile
90   calendarfile="$_DATA/ical/$course"
91   unset key
92
93   declare -A tags
94   declare -A values
95   ics_parse "$calendarfile" |while read -r line; do
96     declare -A tag
97     case "$line" in
98       value*) eval "$line";;
99       tag*)   eval "$line";;
100       key*)
101         if [ -z "$key" ]; then
102           eval "$line"
103         else
104           values[$key]="$(tex_clean "$value")"
105           for t in ${(k)tag}; do
106             tags[${key}_$t]="$tag[$t]"
107           done
108           eval "$line"
109           if [ -n "$values[$key]" ]; then
110             n=0
111             while [ -n "$values[$key$n]" ]; do n=$(($n + 1)); done
112             key=$key$n
113           fi
114           unset value
115           unset tag
116         fi
117       ;;
118     esac
119   done
120
121   dtstart="$values[DTSTART]"
122   [ -z "$dtstart" ] && dtstart=$(date +%Y%m%dT%H%M%S)
123   echo "$dtstart" |case "$dtstart" in
124     *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';;
125     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';;
126     *)     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';;
127   esac |read dts_date
128   rrule="$values[RRULE]"
129   rr_int="$(echo $rrule |sed -rn 's:^.*INTERVAL=([0-9]+)(;.*)?$:\1:p')"
130   rr_freq="$(echo $rrule |sed -rn 's:^.*FREQ=(YEARLY|MONTHLY|WEEKLY|DAILY)(;.*)?$:\1:p')"
131   case "$rr_freq" in
132     YEARLY) rec="$rr_int year";;
133     MONTHLY) rec="$rr_int month";;
134     DAILY) rec="$rr_int day";;
135     *) rec="$rr_int week";;
136   esac
137
138   next_date="$dts_date"
139   n=10
140   while [ $n -gt 0 ]; do
141     if [ "$(date -d "$next_date" +%s)" -gt "$(date +%s)" ]; then
142       dtlist="$dtlist & $(date -d "$next_date" +"%d. %b.")"
143       n=$(($n - 1))
144     fi
145     next_date="$(date -d "$next_date + $rec" +%Y-%m-%d)"
146   done
147
148   echo "$dtlist"
149 }
150
151 if [ -r "${_DATA}/ical/${course}" ]; then
152   . ${_EXEC}/templates/course_print.sh >"${_DATA}/temp/courselist_${course}.tex"
153   [ -e "${_DATA}/temp/courselist_${course}.pdf" ] && rm "${_DATA}/temp/courselist_${course}.pdf"
154   "$pdflatex" -halt-on-error -output-directory "${_DATA}/temp/" "${_DATA}/temp/courselist_${course}.tex" |debug >/dev/null
155   "$pdflatex" -halt-on-error -output-directory "${_DATA}/temp/" "${_DATA}/temp/courselist_${course}.tex" |debug >/dev/null
156 fi
157 if [ -r "${_DATA}/temp/courselist_${course}.pdf" ]; then
158   echo 'Content-Type: application/x-pdf\n'
159   cat "${_DATA}/temp/courselist_${course}.pdf"
160 fi