simplified vcf parser, enabled field for health insurance
authorpaul <paul@plutz.net>
Fri, 29 Jan 2016 19:31:17 +0000 (19:31 +0000)
committerpaul <paul@plutz.net>
Fri, 29 Jan 2016 19:31:17 +0000 (19:31 +0000)
svn path=/trunk/; revision=78

actions/update_card.sh
globals.sh
pages/cards.sh
templates/attendees.css.sh
templates/edit_client.sh
templates/view_attendee.sh
templates/view_client.sh

index 2250f19..1be1676 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/zsh
 
-# Copyright 2014 Paul Hänsch
+# Copyright 2014, 2016 Paul Hänsch
 #
 # This file is part of Confetti.
 # 
@@ -29,32 +29,35 @@ tempfile="$_DATA/temp/$card"
 cardfile="$_DATA/vcard/$card"
 attfile="$_DATA/mappings/attendance"
 
-_POST[0N]="$(echo "${_POST[0N]}" |sed 's:;: :')"
-_POST[1N]="$(echo "${_POST[1N]}" |sed 's:;: :')"
-_POST[2N]="$(echo "${_POST[2N]}" |sed 's:;: :')"
-_POST[3N]="$(echo "${_POST[3N]}" |sed 's:;: :')"
-_POST[4N]="$(echo "${_POST[4N]}" |sed 's:;: :')"
+_POST[0N]="${_POST[0N]//;/,}"
+_POST[1N]="${_POST[1N]//;/,}"
+_POST[2N]="${_POST[2N]//;/,}"
+_POST[3N]="${_POST[3N]//;/,}"
+_POST[4N]="${_POST[4N]//;/,}"
+[ -n "${_POST[hi_number]}" -o -n "${_POST[hi_company]}" ] \
+&& _POST[X-HEALTH-INSURANCE]="${_POST[hi_number]//;/,};${_POST[hi_company]//;/,}"
 
-echo "BEGIN:VCARD\r" >"$tempfile"
-echo "VERSION:4.0\r" >>"$tempfile"
-echo "N:${_POST[0N]};${_POST[1N]};${_POST[2N]};${_POST[3N]};${_POST[4N]}\r" >>"$tempfile"
-echo "UID:${_POST[UID]}\r" >>"$tempfile"
+sed -r 's;$;\r;' >"$tempfile" <<EOF
+BEGIN:VCARD
+VERSION:4.0
+N:${_POST[0N]};${_POST[1N]};${_POST[2N]};${_POST[3N]};${_POST[4N]}
+UID:${_POST[UID]}
+$(
 for field in $VCF_FIELDS; 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))
+  for key in $field $field{0..100}; do
+    [ -z "$_POST[$key]" ] && break
+    value="$(printf %s "$_POST[$key]" |sed -r ':a;N;$!ba;s:\n:\\n:g;s:\r:\\r:g')"
+    printf '%s:%s\n' "${field}" "$value"
   done
-done >>"$tempfile"
+done
+[ "${_POST[action]}" = addfield ] && printf '%s:\n' "${_POST[newfield]}"
+)
+END:VCARD
+EOF
 
 case "${_POST[action]}" in
   addfield)
-    echo "${_POST[newfield]}:\r" >>"$tempfile"
-    echo "END:VCARD\r" >>"$tempfile"
-    echo -n "Location: ?p=cards${filter}${filtertype}${order}&edit=$card\n\n"
+    redirect "?p=cards${filter}${filtertype}${order}&edit=$card"
     ;;
   update)
     attendance=()
@@ -72,18 +75,17 @@ case "${_POST[action]}" in
       touch "$_DATA/ical/$course"
     done
 
-    echo "END:VCARD\r" >>"$tempfile"
     mv "$tempfile" "$cardfile"
-    echo -n "Location: ?p=cards${filter}${filtertype}${order}#$card\n\n"
+    redirect "?p=cards${filter}${filtertype}${order}#$card"
     ;;
   cancel)
     rm "$tempfile"
     [ -f "$cardfile" ] \
-      && echo -n "Location: ?p=cards${filter}${filtertype}${order}#$card\n\n" \
-      || echo -n "Location: ?p=cards${filter}${filtertype}${order}\n\n"
+    && redirect "?p=cards${filter}${filtertype}${order}#$card" \
+    || redirect "?p=cards${filter}${filtertype}${order}"
     ;;
   delete)
     rm "$tempfile" "$cardfile"
-    echo -n "Location: ?p=cards${filter}${filtertype}${order}\n\n"
+    redirect "?p=cards${filter}${filtertype}${order}"
     ;;
 esac
index 5a9d9fe..114dde6 100755 (executable)
@@ -26,10 +26,12 @@ uuidgenerator(){
   head -c16 /dev/urandom |sha1sum - |cut -c1-32
 }
 
-VCF_FIELDS=(PHOTO LOGO FN NICKNAME SOUND GENDER KIND TITLE ROLE ORG MEMBER CATEGORIES ANNIVERSARY BDAY EMAIL TEL IMPP ADR URL LANG NOTE RELATED X-ZACK-JOINDATE X-ZACK-LEAVEDATE)
+VCF_FIELDS=(PHOTO LOGO FN NICKNAME SOUND GENDER KIND TITLE ROLE ORG MEMBER CATEGORIES ANNIVERSARY BDAY EMAIL TEL IMPP ADR URL LANG NOTE RELATED X-ZACK-JOINDATE X-ZACK-LEAVEDATE X-HEALTH-INSURANCE X-HEALTH-INSURANCE-NOCONTRIB X-CLIENT-REFERRAL)
 
 case "${PROFILE}" in
 medical)
+  data_dirs vcard cache temp mappings
+  [ -z "$NAVIGATION" ] && NAVIGATION=(cards)
 ;;
 circus)
   data_dirs vcard ical cache temp mappings
index f2675ba..c045b5b 100755 (executable)
@@ -78,124 +78,51 @@ listcards() {
 vcf_parse() {
   tr -d '\n' <"$1" |sed -r 's:\r ::g;s:\r:\n:g' \
   | sed -rn '
-    s:^PHOTO:001 PHOTO:p;
-    s:^X-MS-CARDPICTURE:001 PHOTO:p;
-    s:^LOGO:002 LOGO:p;
-    s:^FN:003 FN:p;
-    s:^N[\:;]:004 &:p
-    s:^NICKNAME:005 NICKNAME:p;
-    s:^SOUND:006 SOUND:p;
-    s:^GENDER:007 GENDER:p;
-    s:^X-GENDER:007 GENDER:p;
-    s:^KIND:008 KIND:p;
-    s:^TITLE:009 TITLE:p;
-    s:^ROLE:010 ROLE:p;
-    s:^ORG:011 ORG:p;
-    s:^MEMBER:012 MEMBER:p;
-    s:^CATEGORIES:013 CATEGORIES:p;
-    s:^ANNIVERSARY:014 ANNIVERSARY:p;
-    s:^X-ANNIVERSARY:014 ANNIVERSARY:p;
-    s:^X-EVOLUTION-ANNIVERSARY:014 ANNIVERSARY:p;
-    s:^X-KADDRESSBOOK-X-Anniversary:014 ANNIVERSARY:p;
-    s:^BDAY:015 BDAY:p;
-    s:^EMAIL:016 EMAIL:p;
-    s:^TEL:017 TEL:p;
-    s:^IMPP:018 IMPP:p;
-    s:^X-AIM(;[^"\:]+|;"[^"]+")*\:(.*)$:018 IMPP\1\:aim\:\2:p;
-    s:^X-ICQ(;[^"\:]+|;"[^"]+")*\:(.*)$:018 IMPP\1\:aim\:\2:p;
-    s:^X-GOOGLE-TALK(;[^"\:]+|;"[^"]+")*\:(.*)$:018 IMPP\1\:xmpp\:\2:p;
-    s:^X-JABBER(;[^"\:]+|;"[^"]+")*\:(.*)$:018 IMPP\1\:xmpp\:\2:p;
-    s:^X-MSN(;[^"\:]+|;"[^"]+")*\:(.*)$:018 IMPP\1\:msn\:\2:p;
-    s:^X-YAHOO(;[^"\:]+|;"[^"]+")*\:(.*)$:018 IMPP\1\:ymsgr\:\2:p;
-    s:^X-SIP(;[^"\:]+|;"[^"]+")*\:(sip\:)?(.*)$:018 IMPP\1\:sip\:\3:p;
-    s:^ADR:019 ADR:p;
-    s:^LABEL(;[^"\:]+|;"[^"]+")*\:(.*)$:019 ADR;LABEL="\2"\1\::p;
-    s:^URL:021 URL:p;
-    s:^X-EVOLUTION-BLOG-URL:021 URL:p;
-    s:^LANG:022 LANG:p;
-    s:^NOTE:023 NOTE:p;
-    s:^UID:026 UID:p;
+    s:^X-MS-CARDPICTURE:PHOTO:p;
+    s:^X-GENDER:GENDER:p;
+    s:^X-ANNIVERSARY:ANNIVERSARY:p;
+    s:^X-EVOLUTION-ANNIVERSARY:ANNIVERSARY:p;
+    s:^X-KADDRESSBOOK-X-Anniversary:ANNIVERSARY:p;
+    s:^X-AIM(;[^"\:]+|;"[^"]+")*\:(.*)$:IMPP\1\:aim\:\2:p;
+    s:^X-ICQ(;[^"\:]+|;"[^"]+")*\:(.*)$:IMPP\1\:aim\:\2:p;
+    s:^X-GOOGLE-TALK(;[^"\:]+|;"[^"]+")*\:(.*)$:IMPP\1\:xmpp\:\2:p;
+    s:^X-JABBER(;[^"\:]+|;"[^"]+")*\:(.*)$:IMPP\1\:xmpp\:\2:p;
+    s:^X-MSN(;[^"\:]+|;"[^"]+")*\:(.*)$:IMPP\1\:msn\:\2:p;
+    s:^X-YAHOO(;[^"\:]+|;"[^"]+")*\:(.*)$:IMPP\1\:ymsgr\:\2:p;
+    s:^X-SIP(;[^"\:]+|;"[^"]+")*\:(sip\:)?(.*)$:IMPP\1\:sip\:\3:p;
+    s:^LABEL(;[^"\:]+|;"[^"]+")*\:(.*)$:ADR;LABEL="\2"\1\::p;
+    s:^X-EVOLUTION-BLOG-URL:URL:p;
 
-    s:^RELATED:025 RELATED:p;
-    s:^AGENT:025 RELATED\;TYPE=agent:p;
-    s:^X-ASSISTANT:025 RELATED\;TYPE=assistant;VALUE=text:p;
-    s:^X-EVOLUTION-ASSISTANT:025 RELATED\;TYPE=assistant;VALUE=text:p;
-    s:^X-KADDRESSBOOK-X-AssistantsName:025 RELATED\;TYPE=assistant;VALUE=text:p;
-    s:^X-MANAGER:025 RELATED\;TYPE=manager;VALUE=text:p;
-    s:^X-EVOLUTION-MANAGER:025 RELATED\;TYPE=manager;VALUE=text:p;
-    s:^X-KADDRESSBOOK-X-ManagersName:025 RELATED\;TYPE=manager;VALUE=text:p;
-    s:^X-SPOUSE:025 RELATED\;TYPE=spouse;VALUE=text:p;
-    s:^X-EVOLUTION-SPOUSE:025 RELATED\;TYPE=spouse;VALUE=text:p;
-    s:^X-KADDRESSBOOK-X-SpouseName:025 RELATED\;TYPE=spouse;VALUE=text:p;
+    s:^AGENT:RELATED\;TYPE=agent:p;
+    s:^X-ASSISTANT:RELATED\;TYPE=assistant;VALUE=text:p;
+    s:^X-EVOLUTION-ASSISTANT:RELATED\;TYPE=assistant;VALUE=text:p;
+    s:^X-KADDRESSBOOK-X-AssistantsName:RELATED\;TYPE=assistant;VALUE=text:p;
+    s:^X-MANAGER:RELATED\;TYPE=manager;VALUE=text:p;
+    s:^X-EVOLUTION-MANAGER:RELATED\;TYPE=manager;VALUE=text:p;
+    s:^X-KADDRESSBOOK-X-ManagersName:RELATED\;TYPE=manager;VALUE=text:p;
+    s:^X-SPOUSE:RELATED\;TYPE=spouse;VALUE=text:p;
+    s:^X-EVOLUTION-SPOUSE:RELATED\;TYPE=spouse;VALUE=text:p;
+    s:^X-KADDRESSBOOK-X-SpouseName:RELATED\;TYPE=spouse;VALUE=text:p;
 
-    s:^BEGIN.*$:000 &:p;
-    s:^CALADRURI.*$::;
-    s:^CALURI.*$::;
-    s:^CLASS.*$::;
-    s:^CLIENTPIDMAP.*$::;
-    s:^END.*$:100 &:p;
-    s:^FBURL.*$::;
-    s:^GEO.*$::;
-    s:^MAILER.*$::;
-    s:^NAME.*$::;
-    s:^PRODID.*$::;
-    s:^PROFILE.*$::;
-    s:^REV.*$::;
-    s:^SORT-STRING.*$::;
-    s:^SOURCE.*$::;
-    s:^TZ.*$::;
-    s:^VERSION.*$:000 VERSION\:4.0:p;
-    s:^XML.*$::;
-
-    s:^([A-Z].*)$:024 \1:p;
+    s:^([A-Z].*)$:\1:p;
     ' \
-  |sort |while read -r line; do
-    case "$line" in
-      00[012]*)
-       echo -E "$line"
-       ;;
-      003*)
-       fn=$(echo -E "$line" |sed -r 's:^[0-9]{3} ([^;\:]+)(;[^"\:]+|;"[^"]+")*\:(.*)$:\3:g' |tr -d '\r')
-       ;;
-      004*)
-       n=$(echo -E "$line" \
-         |sed -rn 's:^([0-9]{3} )([^;\:]+)(;[^"\:]+|;"[^"]+")*\:([^;]*)(\;[^;]*)(\;[^;]*)?(\;[^;]*)?(\;[^;]*)?$:\7 \5 \6 \4 \8:gp' \
-         |sed -r 's:,: :;s:\;: :g;s: +: :g' \
-         |tr -d '\r'
-       )
-       echo -E "$line"
-       ;;
-      005*)
-       nick=$(echo -E "$line" |sed -r 's:^[0-9]{3} ([^;\:]+)(;[^"\:]+|;"[^"]+")*\:(.*)$:\3:g' |tr -d '\r')
-       echo -E "$line"
-       ;;
-      *)
-        [ -n "$n" ] && fn="$n"
-       #[ -n "$fn" -a -n "$nick" ] && fn="$fn aka. $nick"
-       [ -n "$fn" ] && echo -E "003 FN:$fn" \
-                     || echo -E "003 FN:$nick"
-       echo -E "$line"
-       cat
-       ;;
-    esac
-  done |tr -d '\r' \
-  | sed -r 's:^[0-9]{3} ([^;\:]+)(;[^"\:]+|;"[^"]+")*\:(.*)$:key="\1"\nvalue="\3"\ntag=\2:g' \
+  | sed -r 's:^([^;\:]+)(;[^"\:]+|;"[^"]+")*\:(.*)$:key="\1"\nvalue="\3"\ntag=\2:g' \
   | while read -r line; do
     case "$line" in
-      key=*) echo -E "$line"
+      key=*) printf %s\\n "$line"
        ;;
-      value=*) echo -E "$line"
+      value=*) printf %s\\n "$line"
        ;;
       tag=*) ot=''
-            echo -E "$line" \
+            printf %s "$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="$(printf %s "$tag" |sed -r 's:^tag\[([A-Z+_-]+)\]="(.*)"$:\1:')"
+              nv="$(printf %s "$tag" |sed -r 's:^tag\[([A-Z+_-]+)\]="(.*)"$:\2:')"
               [ "$nt" = "$ot" ] && vl="$nv,$vl" || vl="$nv"
-              echo -E "tag[$nt]=\"$vl\""
+              printf %s\\n "tag[$nt]=\"$vl\""
               ot="$nt"
             done
        ;;
index 76f75a5..58896fa 100755 (executable)
@@ -162,6 +162,9 @@ form.card .attendance label input[type=checkbox] {
   max-width: 100%;
   word-wrap: break-word;
 }
+.card .section .item label {
+  font-weight: bold;
+}
 
 .card .section textarea.NOTE {
   min-height: 6em;
index ddb33c3..049f251 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright 2014, 2015 Paul Hänsch
+# Copyright 2014 - 2016 Paul Hänsch
 #
 # This file is part of Confetti.
 # 
@@ -22,11 +22,14 @@ check_a() {
   egrep -q "^${1}.${id}$" "$_DATA/mappings/attendance" && echo 'checked="checked"'
 }
 
-n_last="$(echo "$values[N]" |sed -rn 's:^([^;]*;){0} *([^;]*).*$:\2:p')"
-n_first="$(echo "$values[N]" |sed -rn 's:^([^;]*;){1} *([^;]*).*$:\2:p')"
-n_middle="$(echo "$values[N]" |sed -rn 's:^([^;]*;){2} *([^;]*).*$:\2:p')"
-n_pre="$(echo "$values[N]" |sed -rn 's:^([^;]*;){3} *([^;]*).*$:\2:p')"
-n_post="$(echo "$values[N]" |sed -rn 's:^([^;]*;){4} *([^;]*)*$:\2:p')"
+n_last="$(printf %s "$values[N]" |sed -rn 's:^([^;]*;){0} *([^;]*).*$:\2:p')"
+n_first="$(printf %s "$values[N]" |sed -rn 's:^([^;]*;){1} *([^;]*).*$:\2:p')"
+n_middle="$(printf %s "$values[N]" |sed -rn 's:^([^;]*;){2} *([^;]*).*$:\2:p')"
+n_pre="$(printf %s "$values[N]" |sed -rn 's:^([^;]*;){3} *([^;]*).*$:\2:p')"
+n_post="$(printf %s "$values[N]" |sed -rn 's:^([^;]*;){4} *([^;]*)*$:\2:p')"
+
+hi_number="${values[X-HEALTH-INSURANCE]%;*}"
+hi_company="${values[X-HEALTH-INSURANCE]#*;}"
 
 SUP_FIELDS=(N NICKNAME GENDER BDAY ADR TEL EMAIL X-HEALTH-INSURANCE X-HEALTH-INSURANCE-NOCONTRIB IMPP URL NOTE X-CLIENT-REFERRAL)
 
@@ -101,7 +104,7 @@ cat <<END_HTML
       <option value="" disabled="disabled" selected="selected">$(l10n hi_company)</option>
       $(list_hi_companies |while read f; do echo "<option value=\"$f\">$(l10n $f)</option>"; done)
     </select>
-    <input class="item hi_number" name="hi_number" value="$values[hi_number]" placeholder="$(l10n hi_number)" />
+    <input class="item hi_number" name="hi_number" value="$hi_number" placeholder="$(l10n hi_number)" />
 
   </div>
 
index e1b6530..bdfdc6a 100755 (executable)
 # You should have received a copy of the GNU Affero General Public License
 # along with Confetti.  If not, see <http://www.gnu.org/licenses/>. 
 
+n=$(printf %s "$values[N]" \
+    | sed -rn 's:^([^;]*)(\;[^;]*)(\;[^;]*)?(\;[^;]*)?(\;[^;]*)?$:\4 \2 \3 \1 \5:gp' \
+    | sed -r 's:,: :;s:\;: :g;s: +: :g;s:^ $::;'
+   )
+fullname="${n:-${values[FN]:-${values[NICKNAME]}}}"
+
 cat <<END_HTML
   <div class="section basic">
-    <h2 class="item FN">$values[FN]</h2>
+    <h2 class="item FN">$fullname</h2>
     ${values[GENDER]:+<span class="item GENDER">$(l10n $values[GENDER])</span>}
 
     $(for n in NICKNAME NICKNAME{0..10}; do
index 700420c..47d6d21 100755 (executable)
 # You should have received a copy of the GNU Affero General Public License
 # along with Confetti.  If not, see <http://www.gnu.org/licenses/>. 
 
+n=$(printf %s "$values[N]" \
+    | sed -rn 's:^([^;]*)(\;[^;]*)(\;[^;]*)?(\;[^;]*)?(\;[^;]*)?$:\4 \2 \3 \1 \5:gp' \
+    | sed -r 's:,: :;s:\;: :g;s: +: :g;s:^ $::;'
+   )
+fullname="${n:-${values[FN]:-${values[NICKNAME]}}}"
+
+hi_number="${values[X-HEALTH-INSURANCE]%;*}"
+hi_company="${values[X-HEALTH-INSURANCE]#*;}"
+
 cat <<END_HTML
   <div class="section basic">
-    <h2 class="item FN">$values[FN]</h2>
+    <h2 class="item FN">$fullname</h2>
     ${values[GENDER]:+<span class="item GENDER">$(l10n $values[GENDER])</span>}
 
     $(for n in NICKNAME NICKNAME{0..10}; do
       echo "${values[$n]:+<span class="item NICKNAME">aka. $values[$n]</span>}"
     done)
 
-    ${values[BDAY]:+<span class="item BDAY"><b>*:</b> $values[BDAY]</span>}
-    ${values[X-ZACK-JOINDATE]:+<span class="item X-ZACK-JOINDATE"><b>$(l10n label_join):</b> $values[X-ZACK-JOINDATE]</span>}
-    ${values[X-ZACK-LEAVEDATE]:+<span class="item X-ZACK-LEAVEDATE"><b>$(l10n label_leave):</b> $values[X-ZACK-LEAVEDATE]</span>}
+    ${values[BDAY]:+<span class="item BDAY"><label>*:</label> ${values[BDAY]}</span>}
+    ${values[X-ZACK-JOINDATE]:+<span class="item X-ZACK-JOINDATE"><label>$(l10n label_join):</label> $values[X-ZACK-JOINDATE]</span>}
+    ${values[X-ZACK-LEAVEDATE]:+<span class="item X-ZACK-LEAVEDATE"><label>$(l10n label_leave):</label> $values[X-ZACK-LEAVEDATE]</span>}
     ${values[SOUND]:+<audio controls="controls" class="item SOUND"><source type="audio/ogg" src="data:audio/ogg;base64,$values[SOUND]" /></audio>}
     ${values[PHOTO]:+<img class="item PHOTO" src="data:image/$tags[PHOTO_TYPE];base64,$values[PHOTO]" />}
     ${values[LOGO]:+<img class="item LOGO" src="data:image/$tags[LOGO_TYPE];base64,$values[LOGO]" />}
@@ -60,6 +69,8 @@ cat <<END_HTML
 
   --><div class="section insurance">
     <h3>$(l10n X-HEALTH-INSURANCE)</h3>
+    ${hi_company:+<span class="item hi_comapany">${hi_company}</span>}
+    ${hi_number:+<span class="item hi_number"><label>$(l10n hi_number):</label> ${hi_number}</span>}
   </div><!--
 
   --><div class="section note">