]> git.plutz.net Git - confetti/blobdiff - cards/list.sh
display delete buttons for fields (not functional yet)
[confetti] / cards / list.sh
index cb33637cdbc36c5f4ca7e2166c8c572dc2302653..0ef5eba0a9df9e1367be3e3b716ae000706c2c5d 100755 (executable)
@@ -2,24 +2,8 @@
 
 . "${_EXEC}"/pdiread.sh
 
-card_fullname(){
-  local card="$1" n1 n2 n3 n4 n5
-
-  local N="$(pdi_value "$card" N)"
-  local FN="$(pdi_value "$card" FN)"
-  local NICKNAME="$(pdi_value "$card" NICKNAME)"
-
-  if [ "$FN" ]; then
-    printf %s "$FN"
-  elif [ "$N" ]; then
-    IFS=\; read n1 n2 n3 n4 n5 <<-EOF
-       $(pdi_value "$card" N)
-       EOF
-    printf '%s %s %s %s %s' "$n4" "$n2" "$n3" "$n1" "$n5"
-  elif [ "$NICKNAME" ]; then
-    printf '"%s"' "$NICKNAME"
-  fi
-}
+unescape() { [ $# = 0 ] && sed -E 's;\\(.);\1;g' || printf %s "$*" |sed -E 's;\\(.);\1;g'; }
+upcase=' y;abcdefghijklmnopqrstuvwxyzäöüé;ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜÉ;; '
 
 card_item(){
   local card="$1"
@@ -30,13 +14,13 @@ card_item(){
     cnt="$(pdi_count "$card" "$item")"
 
     case $item in
-      FN) printf '[h2 .item .FN &shy;%s]' "$(card_fullname "$card" |HTML)"
+      FN) printf '[h2 .item .FN &shy;%s]' "$(pdi_value "$card" FN |unescape |HTML)"
         ;;
       GENDER) printf '[span .item .GENDER &shy;%s]' "$(pdi_value "$card" GENDER |l10n)"
         ;;
       NICKNAME) seq 1 $cnt |while read c; do
           printf '[span .item .NICKNAME &shy;aka. "%s"]' \
-                 "$(pdi_value "$card" NICKNAME $c |HTML)"
+                 "$(pdi_value "$card" NICKNAME $c |unescape |HTML)"
         done
         ;;
       X-ZACK-JOINDATE|X-ZACK-LEAVEDATE) if [ $cnt -gt 0 ]; then
@@ -45,54 +29,223 @@ card_item(){
                  "$(pdi_value "$card" "$item" |HTML)"
         fi
         ;;
-      BDAY) if [ $cnt -gt 0 ]; then
-          printf '[span .item .BDAY [b *:] %s]' \
-                 "$(pdi_value "$card" BDAY |grep -xE '[0-9-]+')"
-        fi
+      BDAY)
+       [ $cnt -gt 0 ] && printf '[span .item .BDAY [b *:] %s]' \
+                                "$(pdi_value "$card" BDAY |grep -xE '[0-9-]+')"
         ;;
-      SOUND) if [ $cnt -gt 0 ]; then
-          printf '[audio .item .SOUND controls="controls"
-                    [source type="audio/ogg" src="data:audio/ogg;base64,%s"]
-                  ]' \
-                 "$(pdi_value "$card" SOUND |grep -xE '[a-zA-Z0-9/+=]+')"
-        fi
+      SOUND)
+        [ $cnt -gt 0 ] && printf '[audio .item .SOUND controls="controls"
+                                    [source type="audio/ogg" src="data:audio/ogg;base64,%s"]
+                                  ]' \
+                                  "$(pdi_value "$card" SOUND |grep -xE '[a-zA-Z0-9/+=]+')"
         ;;
-      PHOTO|LOGO) if [ $cnt -gt 0 ]; then 
-          printf '[img .item .%s src="data:image/%s;base64,%s"]' "$item" \
-                 "$(pdi_attrib "$card" "$item" |sed -r 's;^(.*;)?TYPE="?(.+)"?(;.*)?$;\2;')" \
-                 "$(pdi_value "$card" "$item" |grep -xE '[a-zA-Z0-9/+=]+')"
-        fi
+      PHOTO|LOGO)
+        [ $cnt -gt 0 ] && printf '[img .item .%s src="data:image/%s;base64,%s"]' "$item" \
+                                 "$(pdi_attrib "$card" "$item" |sed -E 's;^(.*;)?TYPE="?(.+)"?(;.*)?$;\2;')" \
+                                 "$(pdi_value "$card" "$item" |grep -xE '[a-zA-Z0-9/+=]+')"
         ;;
-      EMAIL) if [ $cnt -gt 0 ]; then
-          printf '[h3 %s]' "$(l10n EMAIL)"
-          seq 1 $cnt |while read c; do
-            printf '[a .item .EMAIL href="mailto:%s" &shy;%s]' \
-                   "$(pdi_value "$card" EMAIL $c |HTML)" \
-                   "$(pdi_value "$card" EMAIL $c |HTML)"
-          done
-        fi
+      EMAIL) 
+        [ $cnt -gt 0 ] && printf '[h3 %s]' "$(l10n EMAIL)"
+        seq 1 $cnt |while read c; do
+          printf '[a .item .EMAIL href="mailto:%s" &shy;%s]' \
+                 "$(pdi_value "$card" EMAIL $c |unescape |HTML)" \
+                 "$(pdi_value "$card" EMAIL $c |unescape |HTML)"
+        done
+        ;;
+      TEL)
+        [ $cnt -gt 0 ] && printf '[h3 %s]' "$(l10n TEL)"
+        seq 1 $cnt |while read c; do
+          teltype="$(pdi_attrib "$card" TEL $c TYPE)"
+          [ "$teltype" ] \
+          && printf '[span .item .TEL [span .type &shy;%s:] %s]' \
+                    "$(l10n "TYPE=$teltype" |HTML)" \
+                    "$(pdi_value "$card" TEL $c |unescape |HTML)" \
+          || printf '[span .item .TEL &shy;%s]' \
+                    "$(pdi_value "$card" TEL $c |unescape |HTML)"
+        done
+        ;;
+      *)[ $cnt -gt 0 ] && printf '[h3 %s]' "$(l10n "$item")"
+        seq 1 $cnt |while read c; do
+          printf '[span .item .%s &shy;%s]' "$item" \
+                 "$(pdi_value "$card" "$item" $c |unescape |HTML)"
+        done
         ;;
-      *) if [ $cnt -gt 0 ]; then
-          printf '[h3 %s]' "$(l10n "$item")"
-          seq 1 $cnt |while read c; do
-            printf '[span .item .%s &shy;%s]' "$item" \
-                   "$(pdi_value "$card" "$item" $c |HTML)"
-          done
+    esac
+  done
+}
+
+edit_item(){
+  local card="$1"
+  local item cnt c
+  shift 1
+
+  for item in $@; do
+    cnt="$(pdi_count "$card" "$item")"
+    [ $cnt -lt 1 ] && cnt=1
+
+    case $item in
+      N)N="$(pdi_value "$card" N)"
+        if [ "$N" ]; then
+          IFS=\; read n1 n2 n3 n4 n5 <<-EOF
+               $N
+               EOF
+        else
+         N="$(pdi_value "$card" FN |unescape)"
+          n1="${N%%[a-z]*}" n1="${N#$n1}"
+          [ "$n1" ] || n1="${N##* }"
+          n2="${N%$n1}"
         fi
+        printf '
+        [h3 %s]
+        [input .item .N name="4N" placeholder="%s" value="%s"]
+        [input .item .N name="2N" placeholder="%s" value="%s"]
+        [input .item .N name="1N" placeholder="%s" value="%s"]
+        [input .item .N name="5N" placeholder="%s" value="%s"]
+        ' "$(l10n "$item")" \
+        "$(l10n n_pre)"   "$(HTML "$n4")" \
+        "$(l10n n_first)" "$(HTML "$n2" "$n3")" \
+        "$(l10n n_last)"  "$(HTML "$n1")" \
+        "$(l10n n_post)"  "$(HTML "$n5")"
+        ;;
+      GENDER)
+        gender="$(pdi_value "$card" GENDER)"
+        printf '
+        [select .item .GENDER name="GENDER"
+          [option value="" disabled="disabled" %s %s]
+          [option value="female" %s %s]
+          [option value="male"   %s %s]
+          [option value="other"  %s %s]
+          [option value="none"   %s %s]
+        ]\n' \
+        "$([ "$gender" = ''       ] && printf 'selected="selected"')" "$(l10n GENDER)" \
+        "$([ "$gender" = 'female' ] && printf 'selected="selected"')" "$(l10n gender_female)" \
+        "$([ "$gender" = 'male'   ] && printf 'selected="selected"')" "$(l10n gender_male)" \
+        "$([ "$gender" = 'other'  ] && printf 'selected="selected"')" "$(l10n gender_other)" \
+        "$([ "$gender" = 'none'   ] && printf 'selected="selected"')" "$(l10n gender_none)"
+        ;;
+      BDAY|X-ZACK-JOINDATE|X-ZACK-LEAVEDATE)
+        printf '[h3 %s]
+        [input .item .%s name="%s" value="%s" placeholder="YYYY-MM-DD"]' \
+        "$(l10n "$item")" "$item" "$item" "$(pdi_value "$card" "$item" |grep -xE '[0-9-]+')"
+        ;;
+      ADR|NOTE)
+        printf '[h3 %s]' "$(l10n "$item")"
+        seq 1 $cnt |while read c; do
+          printf '[checkbox "%s_delete" "%i" .delete #%s_delete_%i][label for="%s_delete_%i" %s]' \
+            "$item" $c "$item" $c "$item" $c "$(l10n delete)"
+          printf '<textarea class="item %s" name="%s">%s</textarea>' \
+            "$item" "$item" "$(pdi_value "$card" "$item" $c |unescape |HTML)"
+        done
+        ;;
+      TEL) printf '[h3 %s]' "$(l10n "$item")"
+        seq 1 $cnt |while read c; do
+          printf '[checkbox "%s_delete" "%i" .delete #%s_delete_%i][label for="%s_delete_%i" %s]' \
+            "$item" $c "$item" $c "$item" $c "$(l10n delete)"
+          teltype="$(pdi_attrib "$card" TEL $c TYPE)"
+          printf '[select .item .teltype name="teltype"
+                    [option value="" disabled="disabled" %s %s]
+                    [option value="HOME" %s %s]
+                    [option value="WORK" %s %s]
+                    [option value="CELL" %s %s]
+                    [option value="FAX"  %s %s]
+                  ]\n' \
+                  "$([ "$teltype" = ''     ] && printf 'selected="selected"')" "$(l10n teltype)" \
+                  "$([ "$teltype" = 'HOME' ] && printf 'selected="selected"')" "$(l10n TYPE=HOME)" \
+                  "$([ "$teltype" = 'WORK' ] && printf 'selected="selected"')" "$(l10n TYPE=WORK)" \
+                  "$([ "$teltype" = 'CELL' ] && printf 'selected="selected"')" "$(l10n TYPE=CELL)" \
+                  "$([ "$teltype" = 'FAX'  ] && printf 'selected="selected"')" "$(l10n TYPE=FAX)"
+
+          printf '[input .item .%s name="%s" value="%s" placeholder="%s"]' \
+            "$item" "$item" "$(pdi_value "$card" "$item" $c |unescape |HTML)" "$(l10n "$item")"
+        done
+        ;;
+      *)printf '[h3 %s]' "$(l10n "$item")"
+        seq 1 $cnt |while read c; do
+          printf '[checkbox "%s_delete" "%i" .delete #%s_delete_%i][label for="%s_delete_%i" %s]' \
+            "$item" $c "$item" $c "$item" $c "$(l10n delete)"
+          printf '[input .item .%s name="%s" value="%s" placeholder="%s"]' \
+            "$item" "$item" "$(pdi_value "$card" "$item" $c |unescape |HTML)" "$(l10n "$item")"
+        done
         ;;
     esac
   done
 }
 
-print_card(){
-  local cardfile="$1"
-  local cachefile="${_DATA}/cache/${cardfile##*/}.cache"
+edit_card(){
+  local cardfile="$_DATA/vcard/$1" 
+  local tempfile card
 
-  if [ "$cachefile" -nt "$cardfile" -a "$cachefile" -nt "${_EXEC}/cards" ]; then
-    cat "$cachefile"
+  . $_EXEC/session_lock.sh
+
+  if ! tempfile="$(CHECK_SLOCK "$cardfile")"; then
+    printf '[div .message %s]' "$(l10n "This card is not set up for editing within this session.")"
   else
-    local card="$(pdi_load "$cardfile")"
-    tee "$cachefile" <<-EOF
+    card="$(pdi_load "$tempfile")"
+    cat <<-EOF
+       [form .card #${cardfile##*/} action="/cards/update_card.sh" method="POST"
+         [input type="hidden" name="tid" value="$(transid ${tempfile})"]
+         [div .section .basic $(
+           edit_item "$card" N GENDER
+           [ "$(pdi_count "$card" NICKNAME)" -gt 0 ] \
+           && edit_item "$card" NICKNAME
+           edit_item "$card" BDAY
+           edit_item "$card" X-ZACK-JOINDATE
+           [ "$(pdi_count "$card" X-ZACK-LEAVEDATE)" -gt 0 ] \
+           && edit_item "$card" X-ZACK-LEAVEDATE
+           card_item "$card" SOUND PHOTO LOGO
+         )]
+         [div .section .phone   $(edit_item "$card" TEL)]
+         [div .section .message $(
+           edit_item "$card" EMAIL
+           [ $(pdi_count "$card" IMPP) -gt 0 ] && edit_item "$card" IMPP
+           [ $(pdi_count "$card" URL ) -gt 0 ] && edit_item "$card" URL
+         )]
+         [div .section .address $(edit_item "$card" ADR)]
+         [div .section .note    $(edit_item "$card" NOTE)]
+         [div .section .attendance
+           [h3 $(l10n course_attendance) ] $(
+           for course in "$_DATA"/ical/*.ics; do
+             printf '[label [input type="checkbox" name="attendance" value="%s" %s] %s]' \
+                    "${course##*/}" \
+                    "$(grep -qF "${course##*/} ${cardfile##*/}" "$_DATA/mappings/attendance" \
+                       && printf 'checked="checked"'
+                    )" \
+                    "$(pdi_value "$(pdi_load "$course")" SUMMARY |unescape |HTML)"
+           done)
+           [h3 $(l10n CATEGORIES) ] $(
+           grep -xE '[^ ]+' "$_DATA"/mappings/categories |while read -r cat; do
+             printf '[label [input type="checkbox" name="attendance" value="%s" %s] %s]' \
+                    "$(HTML "$cat")" \
+                    "$(seq 1 $(pdi_count "$card" CATEGORIES) |while read c; do
+                      pdi_value "$card" CATEGORIES $c |grep -qxF "$cat" \
+                      && printf 'checked="checked"' && break
+                    done)" \
+                    "$(HTML "$cat")"
+           done)
+         ]
+         [div .control
+           [select .item name="newfield"
+             [option value="" disabled="disabled" selected="selected" $(l10n edit_addfieldtext)]
+             $(for f in NICKNAME EMAIL TEL IMPP ADR URL NOTE; do
+               printf '[option value="%s" %s] ' "$f" "$(l10n "$f")"
+             done)
+          ][button .item type="submit" name="action" value="addfield" $(l10n edit_addfield)]
+           [button .item type="submit" name="action" value="update"   $(l10n edit_update)]
+           [input type="checkbox" #delete] [label .item for="delete" $(l10n edit_delete)]
+             [button .item type="submit" name="action" value="delete"]
+           [button .item type="submit" name="action" value="cancel"   $(l10n edit_cancel)]
+         ]
+         [input type="hidden" name="UID" value="$(pdi_value "$card" UID |HTML)"]
+         [input type="hidden" name="card" value="${cardfile##*/}"]
+       ]
+       EOF
+  fi
+}
+
+print_card(){
+  local cardfile="$1"
+  local card="$(pdi_load "$cardfile")"
+  cat <<-EOF
     [div .card #${cardfile##*/}
       [div .section .basic &shy;$(
         card_item "$card" FN GENDER NICKNAME BDAY X-ZACK-JOINDATE X-ZACK-LEAVEDATE SOUND PHOTO LOGO
@@ -105,21 +258,90 @@ print_card(){
         $(grep -F "    ${cardfile##*/}" "$_DATA/mappings/attendance" |while read each discard; do
           printf '[li [a .item .attendance href="/courses#%s" &shy;%s]]' \
                  "$each" \
-                 "$(pdi_value "$(pdi_load "$_DATA/ical/$each")" SUMMARY |HTML)"
+                 "$(pdi_value "$(pdi_load "$_DATA/ical/$each")" SUMMARY |unescape |HTML)"
         done)]
         $(card_item "$card" CATEGORIES)
       ]
       [div .control
-        [a .item href="/cards/${cardfile##*/}?action=edit" $(l10n edit)]
-        [a .item href="/cards/${cardfile##*/}?action=export" $(l10n vcf_export)]
+        [a .item href="/cards/edit_card.sh?card=${cardfile##*/}" $(l10n edit)]
+        [a .item href="/cards/?x=${cardfile##*/}" $(l10n vcf_export)]
       ]
     ]
        EOF
-  fi
 }
 
-list_cards(){
-  for cardfile in "${_DATA}"/vcard/*.vcf; do
-    print_card "$cardfile"
+print_cards(){
+  local cardfile cachefile date size name ldate=0 lsize lname
+
+  while read cardfile; do
+    cachefile="${_DATA}/cache/${cardfile##*/}.cache"
+    # if [ -s "$cachefile" -a "$cachefile" -nt "$cardfile" \
+    #                      -a "$cachefile" -nt "${_EXEC}/cards" ]; then
+    if [ -s "$cachefile" -a "$cachefile" -nt "$cardfile" ]; then
+      cat "$cachefile"
+    else
+      print_card "$cardfile" |tee "$cachefile"
+    fi
   done
 }
+
+filter_cards(){
+  local filter f fex='x;p;'
+
+  filter="$(printf %s "${filter}" \
+            | sed -E 's;[]\/\(\)\\\$\?\.\+\*\;\[\{\}];\\\\&;g;
+                      '"$upcase"
+           )^"
+
+  while [ "$filter" ]; do
+    f="${filter%%^*}" filter="${filter#*^}"
+    case $f in
+      '') break
+        ;;
+      ANY:*) fex="/\n.*(\;[^:]*)?:.*(${f#*:}).*\r?\n/{${fex}}"
+        ;;
+      NAME:*) fex="/\n(N|FN|NICKNAME)(\;[^:]*)?:.*(${f#*:}).*\r?\n/{${fex}}"
+        ;;
+      STREET:*|ZIP:*) fex="/\nADR(\;[^:]*)?:.*(${f#*:}).*\r?\n/{${fex}}"
+        ;;
+      *) fex="/\n${f%%:*}(\;[^:]*)?:.*(${f#*:}).*\r?\n/{${fex}}"
+        ;;
+    esac
+  done
+
+  for cardfile in "${_DATA}"/vcard/*.vcf; do
+    printf '%s\n' "$cardfile"
+    cat "$cardfile"
+  done \
+  | sed -En ':X; /\nEND:VCARD\r?$/!{ N; bX; }; h; s;\n.*$;;; x; s;^[^\n]+\n;;;
+             '"$upcase""$fex"
+}
+
+order_cards() {
+  local cardfile card
+
+  while read cardfile; do
+    card="$(pdi_load "$cardfile")"
+
+    case $order in
+      firstname)
+        printf '%s     %s\n' "$(pdi_value "$card" FN)" "$cardfile"
+        ;;
+      lastname)
+        printf '%s     %s\n' "$(pdi_value "$card" N || pdi_value "$card" FN)" "$cardfile"
+        ;;
+      bdate)
+        printf '%s     %s\n' "$(pdi_value "$card" BDAY || printf 0000-00-00)" "$cardfile"
+        ;;
+    esac
+  done \
+  | sort \
+  | sed -E 's;^.*\t;;g'
+}
+
+list_cards(){
+  filter_cards \
+  | order_cards \
+  | grep -xvF "$edit" \
+  | print_cards
+}