rename attendees section to more generic "cards" to allow alternate views for vcards
[confetti] / pages / cards.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 [ -z "${_GET[order]}" ] && _GET[order]="firstname"
21
22 listcourses() {
23   ls -1 ${_DATA}/ical/*ics |while read file; do
24     icstime="$(sed -rn 's:^DTSTART\:(TZID=.*\:)?([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})Z?\r$:\2-\3-\4 \5\:\6\:\7:p' "$file")"
25     echo "$(date -d "$icstime" "+%u %H%M%S")\t$file"
26   done |sort |sed -r 's:^.*\t(.*/)([^/]+)$:\2:'
27 }
28
29 listcards() {
30   case "${_GET[filtertype]}" in
31     any)
32        grep -il "${_GET[filter]}" ${_DATA}/vcard/*vcf
33       ;;
34     name)
35        egrep -xil "(FN|NICKNAME|N)(;.+)*:.*${_GET[filter]}.*" ${_DATA}/vcard/*vcf
36       ;;
37     street)
38        egrep -xil "(ADR)(;.+)*:([^;]*;){2}${_GET[filter]}.*" ${_DATA}/vcard/*vcf
39       ;;
40     zip)
41        egrep -xil "(ADR)(;.+)*:([^;]*;){5}${_GET[filter]}.*" ${_DATA}/vcard/*vcf
42       ;;
43     telephone)
44        egrep -xil "(TEL)(;.+)*:.*${_GET[filter]}.*" ${_DATA}/vcard/*vcf
45       ;;
46     birth)
47        egrep -xil "(BDAY)(;.+)*:${_GET[filter]}.*" ${_DATA}/vcard/*vcf
48       ;;
49     course)
50       ;;
51     *) ls -1 ${_DATA}/vcard/*vcf 2>/dev/null
52       ;;
53   esac |case "${_GET[order]}" in
54     firstname)
55       while read file; do
56         fn=$(sed -rn 's:^N(;.+)*\:([^;]*;){1} *([^;]*).*$:\3:p' "$file")
57         echo "$fn\t$file"
58       done
59       ;;
60     lastname)
61       while read file; do
62         ln=$(sed -rn 's:^N(;.+)*\:([^;]*;){0} *([^;]*).*$:\3:p' "$file")
63         echo "$ln\t$file"
64       done
65       ;;
66     bdate)
67       while read file; do
68         bd=$(sed -rn 's:^BDAY(;.+)*\:(.*)$:\2:p' "$file")
69         echo "$bd\t$file"
70       done
71       ;;
72     *)
73       sed -r 's:^.*$:x\t&:'
74       ;;
75   esac |sort |sed -r 's:^.*\t(.*/)([^/]+)$:\2:'
76 }
77
78 vcf_parse() {
79   tr -d '\n' <"$1" |sed -r 's:\r ::g;s:\r:\n:g' \
80   | sed -rn '
81     s:^PHOTO:001 PHOTO:p;
82     s:^X-MS-CARDPICTURE:001 PHOTO:p;
83     s:^LOGO:002 LOGO:p;
84     s:^FN:003 FN:p;
85     s:^N[\:;]:004 &:p
86     s:^NICKNAME:005 NICKNAME:p;
87     s:^SOUND:006 SOUND:p;
88     s:^GENDER:007 GENDER:p;
89     s:^X-GENDER:007 GENDER:p;
90     s:^KIND:008 KIND:p;
91     s:^TITLE:009 TITLE:p;
92     s:^ROLE:010 ROLE:p;
93     s:^ORG:011 ORG:p;
94     s:^MEMBER:012 MEMBER:p;
95     s:^CATEGORIES:013 CATEGORIES:p;
96     s:^ANNIVERSARY:014 ANNIVERSARY:p;
97     s:^X-ANNIVERSARY:014 ANNIVERSARY:p;
98     s:^X-EVOLUTION-ANNIVERSARY:014 ANNIVERSARY:p;
99     s:^X-KADDRESSBOOK-X-Anniversary:014 ANNIVERSARY:p;
100     s:^BDAY:015 BDAY:p;
101     s:^EMAIL:016 EMAIL:p;
102     s:^TEL:017 TEL:p;
103     s:^IMPP:018 IMPP:p;
104     s:^X-AIM(;[^"\:]+|;"[^"]+")*\:(.*)$:018 IMPP\1\:aim\:\2:p;
105     s:^X-ICQ(;[^"\:]+|;"[^"]+")*\:(.*)$:018 IMPP\1\:aim\:\2:p;
106     s:^X-GOOGLE-TALK(;[^"\:]+|;"[^"]+")*\:(.*)$:018 IMPP\1\:xmpp\:\2:p;
107     s:^X-JABBER(;[^"\:]+|;"[^"]+")*\:(.*)$:018 IMPP\1\:xmpp\:\2:p;
108     s:^X-MSN(;[^"\:]+|;"[^"]+")*\:(.*)$:018 IMPP\1\:msn\:\2:p;
109     s:^X-YAHOO(;[^"\:]+|;"[^"]+")*\:(.*)$:018 IMPP\1\:ymsgr\:\2:p;
110     s:^X-SIP(;[^"\:]+|;"[^"]+")*\:(sip\:)?(.*)$:018 IMPP\1\:sip\:\3:p;
111     s:^ADR:019 ADR:p;
112     s:^LABEL(;[^"\:]+|;"[^"]+")*\:(.*)$:019 ADR;LABEL="\2"\1\::p;
113     s:^URL:021 URL:p;
114     s:^X-EVOLUTION-BLOG-URL:021 URL:p;
115     s:^LANG:022 LANG:p;
116     s:^NOTE:023 NOTE:p;
117     s:^UID:026 UID:p;
118
119     s:^RELATED:025 RELATED:p;
120     s:^AGENT:025 RELATED\;TYPE=agent:p;
121     s:^X-ASSISTANT:025 RELATED\;TYPE=assistant;VALUE=text:p;
122     s:^X-EVOLUTION-ASSISTANT:025 RELATED\;TYPE=assistant;VALUE=text:p;
123     s:^X-KADDRESSBOOK-X-AssistantsName:025 RELATED\;TYPE=assistant;VALUE=text:p;
124     s:^X-MANAGER:025 RELATED\;TYPE=manager;VALUE=text:p;
125     s:^X-EVOLUTION-MANAGER:025 RELATED\;TYPE=manager;VALUE=text:p;
126     s:^X-KADDRESSBOOK-X-ManagersName:025 RELATED\;TYPE=manager;VALUE=text:p;
127     s:^X-SPOUSE:025 RELATED\;TYPE=spouse;VALUE=text:p;
128     s:^X-EVOLUTION-SPOUSE:025 RELATED\;TYPE=spouse;VALUE=text:p;
129     s:^X-KADDRESSBOOK-X-SpouseName:025 RELATED\;TYPE=spouse;VALUE=text:p;
130
131     s:^BEGIN.*$:000 &:p;
132     s:^CALADRURI.*$::;
133     s:^CALURI.*$::;
134     s:^CLASS.*$::;
135     s:^CLIENTPIDMAP.*$::;
136     s:^END.*$:100 &:p;
137     s:^FBURL.*$::;
138     s:^GEO.*$::;
139     s:^MAILER.*$::;
140     s:^NAME.*$::;
141     s:^PRODID.*$::;
142     s:^PROFILE.*$::;
143     s:^REV.*$::;
144     s:^SORT-STRING.*$::;
145     s:^SOURCE.*$::;
146     s:^TZ.*$::;
147     s:^VERSION.*$:000 VERSION\:4.0:p;
148     s:^XML.*$::;
149
150     s:^([A-Z].*)$:024 \1:p;
151     ' \
152   |sort |while read -r line; do
153     case "$line" in
154       00[012]*)
155         echo -E "$line"
156         ;;
157       003*)
158         fn=$(echo -E "$line" |sed -r 's:^[0-9]{3} ([^;\:]+)(;[^"\:]+|;"[^"]+")*\:(.*)$:\3:g' |tr -d '\r')
159         ;;
160       004*)
161         n=$(echo -E "$line" \
162           |sed -rn 's:^([0-9]{3} )([^;\:]+)(;[^"\:]+|;"[^"]+")*\:([^;]*)(\;[^;]*)(\;[^;]*)?(\;[^;]*)?(\;[^;]*)?$:\7 \5 \6 \4 \8:gp' \
163           |sed -r 's:,: :;s:\;: :g;s: +: :g' \
164           |tr -d '\r'
165         )
166         echo -E "$line"
167         ;;
168       005*)
169         nick=$(echo -E "$line" |sed -r 's:^[0-9]{3} ([^;\:]+)(;[^"\:]+|;"[^"]+")*\:(.*)$:\3:g' |tr -d '\r')
170         echo -E "$line"
171         ;;
172       *)
173         [ -n "$n" ] && fn="$n"
174         #[ -n "$fn" -a -n "$nick" ] && fn="$fn aka. $nick"
175         [ -n "$fn" ] && echo -E "003 FN:$fn" \
176                       || echo -E "003 FN:$nick"
177         echo -E "$line"
178         cat
179         ;;
180     esac
181   done |tr -d '\r' \
182   | sed -r 's:^[0-9]{3} ([^;\:]+)(;[^"\:]+|;"[^"]+")*\:(.*)$:key="\1"\nvalue="\3"\ntag=\2:g' \
183   | while read -r line; do
184     case "$line" in
185       key=*) echo -E "$line"
186         ;;
187       value=*) echo -E "$line"
188         ;;
189       tag=*) ot=''
190              echo -E "$line" \
191              | sed -r 's:^tag=::;s:\;([A-Z+_-]+="[^"]+"|[A-Z+_-]+=[^\;]+):\n\1:g;' \
192              | sed -r 's:([A-Z+_-]+)="?(.*)"?:tag\[\1\]="\2":g' \
193              | sed -r '/^ *$/d' \
194              | sort |while read -r tag; do
195                nt="$(echo -E "$tag" |sed -r 's:^tag\[([A-Z+_-]+)\]="(.*)"$:\1:')"
196                nv="$(echo -E "$tag" |sed -r 's:^tag\[([A-Z+_-]+)\]="(.*)"$:\2:')"
197                [ "$nt" = "$ot" ] && vl="$nv,$vl" || vl="$nv"
198                echo -E "tag[$nt]=\"$vl\""
199                ot="$nt"
200              done
201         ;;
202     esac
203   done \
204   | sed -r 's:[\\$`]:\\&:g'
205 }
206
207 view_card() {  #Parameter: Cardfile
208   id="$1"
209   cardfile="$_DATA/vcard/${id}"
210   cachefile="$_DATA/cache/${id}.cache"
211   unset key
212   if [ "$cachefile" -nt "$cardfile" ]; then
213     cat "$cachefile"
214   else
215     declare -A tags
216     declare -A values
217     vcf_parse "$cardfile" |while read -r line; do
218       declare -A tag
219       case "$line" in
220         value*) eval "$line";;
221         tag*)   eval "$line";;
222         key*)
223           if [ -z "$key" ]; then
224             eval "$line"
225           else
226             values[$key]="$value"
227             for t in ${(k)tag}; do
228               tags[${key}_$t]="$tag[$t]"
229             done
230             eval "$line"
231             if [ -n "$values[$key]" ]; then
232               n=0
233               while [ -n "$values[$key$n]" ]; do n=$(($n + 1)); done
234               key=$key$n
235             fi
236             unset value
237             unset tag
238           fi
239         ;;
240       esac
241     done
242     . $view_card |tee "$cachefile"
243   fi
244 }
245
246 edit_card() {  #Parameter: Cardfile
247   id="$1"
248   cardfile="$_DATA/vcard/$id"
249   tempfile="$_DATA/temp/$id"
250   [ -f "$tempfile" ] && cardfile="$tempfile"
251   unset key
252
253   declare -A tags
254   declare -A values
255   vcf_parse "$cardfile" |while read -r line; do
256     declare -A tag
257     case "$line" in
258       value*) eval "$line";;
259       tag*)   eval "$line";;
260       key*)
261         if [ -z "$key" ]; then
262           eval "$line"
263         else
264           [ -n "$value" ] && values[$key]="$value" || values[$key]='\r'
265           for t in ${(k)tag}; do
266             tags[${key}_$t]="$tag[$t]"
267           done
268           eval "$line"
269           if [ -n "$values[$key]" ]; then
270             n=0
271             while [ -n "$values[${key}${n}]" ]; do n=$(($n + 1)); done
272             key=$key$n
273           fi
274             unset value
275             unset tag
276         fi
277       ;;
278     esac
279   done
280   . $edit_card
281 }