]> git.plutz.net Git - confetti/blobdiff - cards/list.sh
session aware file locking
[confetti] / cards / list.sh
index cb33637cdbc36c5f4ca7e2166c8c572dc2302653..f598cd2b465d0fcf504cd5126124acb00c0fb3e7 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
@@ -59,7 +43,7 @@ card_item(){
         ;;
       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_attrib "$card" "$item" |sed -E 's;^(.*;)?TYPE="?(.+)"?(;.*)?$;\2;')" \
                  "$(pdi_value "$card" "$item" |grep -xE '[a-zA-Z0-9/+=]+')"
         fi
         ;;
@@ -67,8 +51,8 @@ card_item(){
           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)"
+                   "$(pdi_value "$card" EMAIL $c |unescape |HTML)" \
+                   "$(pdi_value "$card" EMAIL $c |unescape |HTML)"
           done
         fi
         ;;
@@ -76,7 +60,7 @@ card_item(){
           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)"
+                   "$(pdi_value "$card" "$item" $c |unescape |HTML)"
           done
         fi
         ;;
@@ -84,6 +68,153 @@ card_item(){
   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)if N="$(pdi_value "$card" N)"; then
+          IFS=\; read n1 n2 n3 n4 n5 <<-EOF
+               $(pdi_value "$card" 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)
+        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]
+        ]
+        ' \
+        "$([ "$(pdi_value "$card" GENDER)" = '' ] && printf 'selected="selected"')" \
+        "$(l10n GENDER)" \
+        "$([ "$(pdi_value "$card" GENDER)" = 'female' ] && printf 'selected="selected"')" \
+        "$(l10n gender_female)" \
+        "$([ "$(pdi_value "$card" GENDER)" = 'male' ] && printf 'selected="selected"')" \
+        "$(l10n gender_male)" \
+        "$([ "$(pdi_value "$card" GENDER)" = 'other' ] && printf 'selected="selected"')" \
+        "$(l10n gender_other)" \
+        "$([ "$(pdi_value "$card" GENDER)" = 'none' ] && printf 'selected="selected"')" \
+        "$(l10n gender_none)"
+        ;;
+      BDAY|X-ZACK-JOIDATE|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 '<textarea class="item %s" name="%s">%s</textarea>' \
+          "$item" "$item" "$(pdi_value "$card" "$item" $c |unescape |HTML)"
+        done
+        ;;
+      *) printf '[h3 %s]' "$(l10n "$item")"
+        seq 1 $cnt |while read c; do
+          printf '[input .item .%s name="%s" value="%s" placeholder="%s"]' \
+          "$item" "$item" "$(pdi_value "$card" "$item" $c |unescape |HTML)" "$(l10n "$item")"
+        done
+        ;;
+    esac
+  done
+}
+
+edit_card(){
+  local cardfile="$_DATA/vcard/$1" 
+  local tempfile card
+
+  . $_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
+    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" 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 ; 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 cachefile="${_DATA}/cache/${cardfile##*/}.cache"
@@ -105,21 +236,78 @@ 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(){
+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" \
+  | while read cardfile; do
     print_card "$cardfile"
   done
 }