- #!/bin/zsh
+ #!/bin/sh
# Copyright 2019 Paul Hänsch
#
order="$(REF o)"
if tempfile="$(SLOCK "$cardfile" "$locktimeout")"; then
- REDIRECT "/cards/?o=${order}&f=${filter}&e=${card}"
+ REDIRECT "/cards/?o=${order}&f=${filter}&e=${card#/}"
elif [ -f "$tempfile" ]; then
SET_COOKIE session message="SESSLOCK"
- REDIRECT "/cards/?o=${order}&f=${filter}#${card}"
+ REDIRECT "/cards/?o=${order}&f=${filter}#${card#/}"
else
SET_COOKIE session message="EDITLOCK"
- REDIRECT "/cards/?o=${order}&f=${filter}#${card}"
+ REDIRECT "/cards/?o=${order}&f=${filter}#${card#/}"
fi
#!/bin/sh
- if [ "$_PATH" = "/cards/cards.css" ]; then
- . $_EXEC/cgilite/file.sh
- FILE $_EXEC/cards/cards.css
- return 0
- fi
-
. $_EXEC/pdiread.sh
. $_EXEC/cards/l10n.sh
. $_EXEC/cards/widgets.sh
. $_EXEC/cards/list.sh
- #unescape() { [ $# = 0 ] && sed -E 's;\\(.);\1;g' || printf %s "$*" |sed -E 's;\\(.);\1;g'; }
upcase=' y;abcdefghijklmnopqrstuvwxyzäöüé;ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜÉ;; '
filter="$(GET f)"
order="$(GET o)"
edit="$(GET e |PATH)"
-[ "$order" ] || order=firstname
+[ "$order" ] || order=lastname
edit="${edit##*/}"
+list_hi_companies(){
+ sed -rn 's;^X-HEALTH-INSURANCE:([^\;]+)\;.*$;\1;p' ${_DATA}/vcard/*vcf \
+ | sort -u
+}
+
{ w_filter_diag
printf '
[form class="newcard" action="/cards/new_card.sh" method="POST"
+ [a href="#top" . %s]
[button type="submit" %s]
- [input name="seed" placeholder="%s"]
- ]' "$(l10n newcard)" "$(l10n vcf_seed_label)"
+ ]' "$(l10n top)" "$(l10n newcard)"
-
[ "$edit" ] && edit_card "$edit"
list_cards
- } | yield_page cards /cards/cards.css
+ } | yield_page cards #/cards/cards.css
- # Copyright 2014, 2016, 2019 Paul Hänsch
+ # Copyright 2014, 2016, 2019, 2021 Paul Hänsch
#
# This file is part of Confetti.
#
l10n(){
local word
- [ $# -eq 0 ] && read -r word || word="$1"
+ [ $# -eq 0 ] && read -r word || word="$*"
case $word in
- PHOTO) printf %s "Foto";;
- LOGO) printf %s "Logo";;
- FN) printf %s "Voller Name";;
- N) printf %s "Name";;
- n_pre) printf %s "Titel";;
- n_first) printf %s "Vorname";;
- n_middle) printf %s "Mittelnamen";;
- n_last) printf %s "Nachname";;
- n_post) printf %s "Zusätze";;
- NICKNAME) printf %s "Spitzname";;
- SOUND) printf %s "Aussprache";;
- GENDER) printf %s "Geschlecht";;
- KIND) printf %s "Typ";;
- TITLE) printf %s "Beruf";;
- ROLE) printf %s "Position";;
- ORG) printf %s "Organisation";;
- MEMBER) printf %s "Mitglied";;
- CATEGORIES) printf %s "Kategorien";;
- ANNIVERSARY) printf %s "Jubiläum";;
- BDAY) printf %s "Geburtstag";;
- EMAIL) printf %s "E-Mail";;
- TEL) printf %s "Telefon";;
- teltype) printf %s "Anschlusstyp:";;
- TYPE=HOME) printf %s "Privat";;
- TYPE=WORK) printf %s "Geschäftlich";;
- TYPE=CELL) printf %s "Mobil";;
- TYPE=FAX) printf %s "Fax";;
- IMPP) printf %s "Chat";;
- ADR) printf %s "Anschrift";;
- URL) printf %s "Webseite";;
- LANG) printf %s "Sprache";;
- NOTE) printf %s "Notiz";;
-
- RELATED) printf %s "Kontakte";;
-
- BEGIN) printf %s "";;
- CALADRURI) printf %s "";;
- CALURI) printf %s "";;
- CLASS) printf %s "";;
- CLIENTPIDMAP) printf %s "";;
- END) printf %s "";;
- FBURL) printf %s "";;
- GEO) printf %s "";;
- MAILER) printf %s "";;
- NAME) printf %s "";;
- PRODID) printf %s "";;
- PROFILE) printf %s "";;
- REV) printf %s "";;
- SORT-STRING) printf %s "";;
- SOURCE) printf %s "";;
- TZ) printf %s "";;
- UID) printf %s "";;
- VERSION) printf %s "";;
- XML) printf %s "";;
-
+ newcard) printf %s "Neuen Eintrag anlegen";;
+
X-HEALTH-INSURANCE) printf %s "Kran­ken­ver­sich­er­ung";;
hi_from_list) printf %s "Aus Liste";;
hi_other) printf %s "Andere";;
hi_status) printf %s "Ver­sich­er­ten­sta­tus";;
X-HEALTH-INSURANCE-NOCONTRIB) printf %s "Zu­zahl­ungs­be­frei­ung";;
X-CLIENT-REFERRAL) printf %s "Empfehl­ung durch";;
- prescriptions) printf %s "Verordnungen";;
- new_prescription) printf %s "Neue Verordnung";;
+ prescriptions) printf %s "Verord­nungen";;
+ new_prescription) printf %s "Neue Verord­nung";;
no_icd) printf %s "Kein ICD Code";;
+ therapy) printf %s "Therapie";;
+ therapies) printf %s "Therapien";;
- X-ZACK-JOINDATE) printf %s "An­mel­de­da­tum";;
- X-ZACK-LEAVEDATE) printf %s "Ab­mel­de­da­tum";;
+ X-ZACK-JOINDATE) printf %s "Anmelde­datum";;
+ X-ZACK-LEAVEDATE) printf %s "Abmelde­datum";;
X-ZACK-JOINDATE_short) printf %s "Anm.";;
X-ZACK-LEAVEDATE_short) printf %s "Abm.";;
-
- top) printf 'Seitenanfang';;
- edit) printf %s "Bearbeiten";;
- edit_categories) printf %s "Kategorien Bearbeiten";;
- vcf_export) printf %s "Vcard Exportieren";;
- control) printf %s "Aktionen";;
- edit_update) printf %s "Daten übernehmen";;
- edit_cancel) printf %s "Abbrechen";;
- edit_delete) printf %s "Eintrag löschen";;
- edit_addfieldtext) printf %s "Neues Feld";;
- edit_addfield) printf %s "+";;
- edit_deletefield) printf %s "X";;
- filter_label) printf %s "Filter";;
- filter_placeholder) printf %s "Begriffe zur Eingrenzung eingeben";;
- filter_type) printf %s "Filtertyp";;
- filter_order) printf %s "Sortierung";;
- filter_any) printf %s "Alles";;
- filter_name) printf %s "Name";;
- filter_firstname) printf %s "Vorname";;
- filter_lastname) printf %s "Nachname";;
- filter_street) printf %s "Straße";;
- filter_zip) printf %s "PLZ.";;
- filter_TEL) printf %s "Telefon";;
- filter_BDAY) printf %s "Geburtsjahr";;
- filter_bdate) printf %s "Geburtsdatum";;
- filter_course) printf %s "Kurs";;
- filter_CATEGORIES) printf %s "Kategorien";;
- filter_apply) printf %s "Filtern";;
- filter_cancel) printf %s "Filter löschen";;
- newcard) printf %s "Neuen Eintrag anlegen";;
- course_attendance) printf %s "Kursteilnahme";;
-
- gender_none) printf %s "keine Angabe";;
- gender_female) printf %s "Weiblich";;
- gender_male) printf %s "Männlich";;
- gender_other) printf %s "Sonstiges";;
-
- female) printf %s "♀";;
- male) printf %s "♂";;
- other) printf %s "⚥";;
- none) printf %s "⚪";;
-
- *) printf %s "$1";;
+ *) l10n_global "$word";;
esac
}
+ # BEGIN) printf %s "";;
+ # CALADRURI) printf %s "";;
+ # CALURI) printf %s "";;
+ # CLASS) printf %s "";;
+ # CLIENTPIDMAP) printf %s "";;
+ # END) printf %s "";;
+ # FBURL) printf %s "";;
+ # GEO) printf %s "";;
+ # MAILER) printf %s "";;
+ # NAME) printf %s "";;
+ # PRODID) printf %s "";;
+ # PROFILE) printf %s "";;
+ # REV) printf %s "";;
+ # SORT-STRING) printf %s "";;
+ # SOURCE) printf %s "";;
+ # TZ) printf %s "";;
+ # UID) printf %s "";;
+ # VERSION) printf %s "";;
+ # XML) printf %s "";;
else
card="$(pdi_load "$tempfile")"
cat <<-EOF
- [form .card #${cardfile##*/} action="/cards/update_card.sh" method="POST"
+ [span .card-anchor #${cardfile##*/}]
+ [form .card 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 .phone $(
+ edit_item "$card" TEL 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 || l10n "(unnamed course)" |unescape |HTML)"
- done)
- [h3 $(l10n CATEGORIES) ] $(
- grep -xE '[^ ]+' "$_DATA"/mappings/categories |while read -r cat; do
- printf '[label [input type="checkbox" name="CATEGORIES" 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 .section .insurance $(edit_item "$card" X-HEALTH-INSURANCE)]
+ [div .section .note $(edit_item "$card" NOTE X-CLIENT-REFERRAL)]
[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)]
+ [div .item .delete label="$(l10n edit_delete)"
+ [input type="checkbox" #delete]
+ [label for="delete" $(l10n edit_delete)]
+ [button type="submit" name="action" value="delete" $(l10n edit_delete)]
+ ]
+ [div .item .newfield
+ [select 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 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)"]
print_card(){
local cardfile="$1"
local card="$(pdi_load "$cardfile")"
+ local N1 N2 N3 N4 N5
+ IFS=\; read N1 N2 N3 N4 N5 <<-EOF
+ $(pdi_value "$card" N |pdi_unescape |HTML)
+ EOF
+
cat <<-EOF
- [span .card-anchor #${cardfile##*/}]
- [div .card
+ [div .card #${cardfile##*/}
- [div .section .basic . $(
- card_item "$card" FN GENDER NICKNAME BDAY X-ZACK-JOINDATE X-ZACK-LEAVEDATE SOUND PHOTO LOGO
+ [div .section .basic
+ [h2 .item .FN . $N4 $N1 $N5]
+ [span .item .firstname . $N2 $N3]
+ $(
+ card_item "$card" GENDER NICKNAME BDAY X-ZACK-JOINDATE X-ZACK-LEAVEDATE SOUND PHOTO LOGO
)]
- [div .section .phone . $(card_item "$card" TEL)]
- [div .section .message . $(card_item "$card" EMAIL IMPP URL)]
- [div .section .address . $(card_item "$card" ADR)]
- [div .section .note . $(card_item "$card" NOTE)]
- [div .section .attendance [h3 $(l10n course_attendance) ] [ul
- $(grep -F " ${cardfile##*/}" "$_DATA/mappings/attendance" |while read each discard; do
- printf '[li [a .item .attendance href="/courses#%s" . %s]]' \
- "$each" \
- "$(pdi_value "$(pdi_load "$_DATA/ical/$each")" SUMMARY || l10n "(unnamed course)" |unescape |HTML)"
- done)]
- $(card_item "$card" CATEGORIES)
- ]
+ [div .section .address $(card_item "$card" ADR)]
+ [div .section .phone $(card_item "$card" TEL EMAL IMPP URL)]
+ [div .section .insurance $(card_item "$card" X-HEALTH-INSURANCE)]
+ [div .section .note $(card_item "$card" NOTE X-CLIENT-REFERRAL)]
+ [div .section .therapies $(card_item "$card" therapies)]
[div .control
[a .item href="/cards/edit_card.sh?card=${cardfile##*/}" $(l10n edit)]
[a .item href="/cards/export_card.sh?card=${cardfile##*/}" $(l10n vcf_export)]
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
done
}
-filter_attendance(){
- fatt="$1"
- attfile="$_DATA/mappings/attendance"
-
- if [ ! "$fatt" ]; then
- # debug 'list all'
- printf '%s\n' "$_DATA/vcard"/*.vcf
- elif [ "${fatt#* }" = "${fatt}" ]; then
- # debug "list $fatt"
- grep -xiE "(${fatt}) .+vcf" "$attfile" \
- | while read vcf; do
- printf '%s/vcard/%s\n' "$_DATA" "${vcf##* }"
- done
- else
- # debug "filter ${fatt%% *}"
- filter_attendance "${fatt#* }" \
- | while read vcf; do
- grep -xiE "(${fatt%% *}) ${vcf##*/}" "$attfile"
- done \
- | while read vcf; do
- printf '%s/vcard/%s\n' "$_DATA" "${vcf##* }"
- done
- fi
-}
-
filter_cards(){
local filter f fex='x;p;'
filter="$(printf %s "${filter}" \
- | sed -E 's;[]\/\(\)\\\$\?\.\+\*\;\[\{\}];\\\\&;g;
+ | sed -E 's;[]\/\(\)\\\$\?\.\+\*\;\[\{\}];\\&;g;
'"$upcase"
)^"
while [ "$filter" ]; do
f="${filter%%^*}" filter="${filter#*^}"
+ debug "Filter: $f"
case $f in
'') break
;;
- ANY:*) fex="/\n.*(\;[^:]*)?:.*(${f#*:}).*\r?\n/{${fex}}"
- COURSE:*) fatt="${fatt}${fatt:+ }${f#*:}"
- ;;
+ ANY:*) fex="/\n.*(\;[^:]*)?:[^\n]*(${f#*:})[^\n]*\r?\n/{${fex}}"
;;
- NAME:*) fex="/\n(N|FN|NICKNAME)(\;[^:]*)?:[^\n]*(${f#*:}).*\r?\n/{${fex}}"
+ NAME:*) fex="/\n(N|FN|NICKNAME)(\;[^:]*)?:[^\n]*(${f#*:})[^\n]*\r?\n/{${fex}}"
;;
- STREET:*|ZIP:*) fex="/\nADR(\;[^:]*)?:[^\n]*(${f#*:}).*\r?\n/{${fex}}"
+ STREET:*|ZIP:*) fex="/\nADR(\;[^:]*)?:[^\n]*(${f#*:})[^\n]*\r?\n/{${fex}}"
;;
- *) fex="/\n${f%%:*}(\;[^:]*)?:[^\n]*(${f#*:}).*\r?\n/{${fex}}"
+ *) fex="/\n${f%%:*}(\;[^:]*)?:[^\n]*(${f#*:})[^\n]*\r?\n/{${fex}}"
;;
esac
done
- # for cardfile in "${_DATA}"/vcard/*.vcf; do
- filter_attendance "$fatt" |while read cardfile; do
- printf '%s\n' "$cardfile"
- cat "$cardfile"
+ for cardfile in "${_DATA}"/vcard/*.vcf; do
+ printf '%s\n' "$cardfile" "$(grep -vxE " *${CR}?" "$cardfile")"
done \
- | sed -nE ':X; /\nEND\;?:VCARD\r?$/!{ N; bX; }; h; s;\n.*$;;; x; s;^[^\n]+\n;;;
+ | sed -En ':X; /\nEND;?:VCARD\r?$/!{ N; bX; }; h; s;\n.*$;;; x; s;^[^\n]+\n;;;
'"$upcase""$fex"
}
- #!/bin/zsh
+ #!/bin/sh
- # Copyright 2014, 2016, 2019 Paul Hänsch
+ # Copyright 2014, 2016, 2019, 2020, 2021 Paul Hänsch
#
# This file is part of Confetti.
#
. "$_EXEC/pdiread.sh"
. "$_EXEC/session_lock.sh"
+ . "$_EXEC/cgilite/storage.sh"
unset filter order card action newfield
--unset cardfile attfile tempfile
++unset cardfile tempfile
unset vcf field cnt delete_key
filter="$(REF f)"
order="$(REF o)"
- card="$(POST card |PATH)"
- cardfile="$_DATA/vcard/${card##*/}"
- attfile="$_DATA/mappings/attendance"
+ card="$(POST card |PATH)"; card="${card##*/}"
+ cardfile="$_DATA/vcard/${card}"
-attfile="$_DATA/mappings/attendance"
action="$(POST action)"
newfield="$(POST newfield |grep -m 1 -xE '[A-Z][A-Z0-9-]*')"
exit 0
fi
-vcf_escape(){
- for each in "$@"; do
- printf %s\\n "$each" \
- | sed -E ':X;$!{N;bX}; s;\r\n;\n;g; s;([;,\\]);\\\1;g; s;\n;\\n;g;'
- done \
- | sed -E ':X;$!{N;bX}; s;\n;\;;g'
-}
-
# [ "${_POST[hi_select]}" = "list" ] || _POST[hi_company]="${_POST[hi_other]}"
# [ -n "${_POST[hi_company]}${_POST[hi_number]}${_POST[hi_status]}" ] \
-# && _POST[X-HEALTH-INSURANCE]="$(vcf_escape "${_POST[hi_company]}" "${_POST[hi_number]}" "${_POST[hi_status]}")"
+# && _POST[X-HEALTH-INSURANCE]="$(pdi_escape "${_POST[hi_company]}" "${_POST[hi_number]}" "${_POST[hi_status]}")"
- # vcf="$(pdi_load "$cardfile")"
vcf="$(pdi_load "$tempfile")"
- vcf="$(pdi_update_value "$vcf" N 1 "$(pdi_escape "$(POST 1N)" "$(POST 2N)" "$(POST 3N)" "$(POST 4N)" "$(POST 5N)")")"
- vcf="$(pdi_update_value "$vcf" FN 1 "$(pdi_escape "$(POST 4N) $(POST 2N) $(POST 3N) $(POST 1N) $(POST 5N)" \
- | sed -E 's;^ +;;; s; +$;;; s; +; ;g;')" )"
+ n1="$(POST 1N)" n2="$(POST 2N)" n3="$(POST 3N)" n4="$(POST 4N)" n5="$(POST 5N)"
+ # 3N (Middle Names) is not actually used
+ n3="${n2#${n2%% *}}"
+
+ vcf="$(pdi_update_value "$vcf" N 1 "$(vcf_escape "$n1" "${n2%% *}" "${n3# }" "$n4" "$n5")")"
+ vcf="$(pdi_update_value "$vcf" FN 1 "$(vcf_escape "$n4 $n2 $n1 $n5" |sed -E 's;(^ +| +$);;g; s; +; ;g;')")"
+ vcf="$(printf '%s\n' "$vcf" |sed -E "/^CATEGORIES;[^:]*:.*$/d")"
for field in $(POST_KEYS |grep -xE '[A-Z][A-Z0-9-]*'); do
for cnt in $(seq 1 $(POST_COUNT "$field")); do
case "$field" in
# (TEL)
- # printf '%s;TYPE=%s:%s\r\n' "${field}" "${_POST[phonetype${key#TEL}]}" "$(vcf_escape "$(POST "$field" "$cnt")")"
+ # printf '%s;TYPE=%s:%s\r\n' "${field}" "${_POST[phonetype${key#TEL}]}" "$(pdi_escape "$(POST "$field" "$cnt")")"
# ;;
+ X-HEALTH-INSURANCE)
+ hi_select="$(POST "$field" "$cnt")"
+ if [ "$hi_select" = list ]; then
+ vcf="$(pdi_update_value "$vcf" "$field" "$cnt" "$(pdi_escape "$(POST "hi_company" "$cnt")" \
+ "$(POST "hi_number" "$cnt")" \
+ "$(POST "hi_status" "$cnt")" \
+ )")"
+ elif [ "$hi_select" = other ]; then
+ vcf="$(pdi_update_value "$vcf" "$field" "$cnt" "$(pdi_escape "$(POST "hi_other" "$cnt")" \
+ "$(POST "hi_number" "$cnt")" \
+ "$(POST "hi_status" "$cnt")" \
+ )")"
+ fi
+ ;;
TEL)
vcf="$(pdi_update_attrib "$vcf" TEL $cnt TYPE="$(POST teltype $cnt |grep -Exm1 'HOME|WORK|CELL|FAX')")"
- vcf="$(pdi_update_value "$vcf" "$field" "$cnt" "$(vcf_escape "$(POST "$field" "$cnt")")")"
+ vcf="$(pdi_update_value "$vcf" "$field" "$cnt" "$(pdi_escape "$(POST "$field" "$cnt")")")"
;;
*)
- vcf="$(pdi_update_value "$vcf" "$field" "$cnt" "$(vcf_escape "$(POST "$field" "$cnt")")")"
+ vcf="$(pdi_update_value "$vcf" "$field" "$cnt" "$(pdi_escape "$(POST "$field" "$cnt")")")"
;;
esac
done; done
if [ "$action" = addfield ]; then
vcf="$(pdi_update_value "$vcf" "$newfield" $(( $(pdi_count "$vcf" "$newfield") + 1 )) '')"
fi
-printf '%s' "$vcf" |grep -vx '' >"$tempfile"
+printf '%s' "$vcf" | sed -E '/^$/d; s/^([^:]+);:/\1:/;' >"$tempfile"
case "$action" in
addfield)
- REDIRECT "/cards/?o=${order}&f=${filter}&e=${card}"
+ REDIRECT "/cards/?o=${order}&f=${filter}&e=${card#/}"
;;
update)
- # attendance=()
- # for att in attendance attendance{0..100}; do
- # [ -n "${_POST[$att]}" ] && attendance+=("${_POST[$att]}")
- # done
- # sed -rn 's:^(.+)'$card'$:\1:p' "$attfile" |while read course; do
- # touch "$_DATA/ical/$course"
- # done
- # sed -i -r '/^(.+)\t'$card'$/d' "$attfile"
- # for each in $attendance; do
- # echo "$each\t$card"
- # done >>"$attfile"
- # sed -rn 's:^(.+)'$card'$:\1:p' "$attfile" |while read course; do
- # touch "$_DATA/ical/$course"
- # done
- if LOCK "$attfile"; then
- grep -F " ${card}" "$attfile" |while read course junk; do
- touch "$_DATA/ical/${course}"
- done
- sed -i -E "/^.+ ${card}\$/d" "$attfile"
- seq 1 $(POST_COUNT attendance) |while read n; do
- printf '%s %s\n' "$(POST attendance $n)" "$card"
- done >>"$attfile"
- grep -F " ${card}" "$attfile" |while read course junk; do
- touch "$_DATA/ical/${course}"
- done
- RELEASE "$attfile"
- else
- SET_COOKIE 0 message="COULD NOT UPDATE COURSE MAPPINGS"
- fi
--
cp "$tempfile" "$cardfile"
RELEASE_SLOCK "$cardfile"
- REDIRECT "/cards/?o=${order}&f=${filter}#${card}"
+ REDIRECT "/cards/?o=${order}&f=${filter}#${card#/}"
;;
cancel)
RELEASE_SLOCK "$cardfile"
[ -f "$cardfile" ] \
- && REDIRECT "/cards/?o=${order}&f=${filter}#${card}" \
+ && REDIRECT "/cards/?o=${order}&f=${filter}#${card#/}" \
|| REDIRECT "/cards/?o=${order}&f=${filter}"
;;
delete)
rm "$cardfile"
RELEASE_SLOCK "$cardfile"
- if LOCK "$attfile"; then
- grep -F " ${card}" "$attfile" |while read course junk; do
- touch "$_DATA/ical/${course}"
- done
- sed -i -E "/^.+ ${card}\$/d" "$attfile"
- RELEASE "$attfile"
- else
- SET_COOKIE 0 message="COULD NOT UPDATE COURSE MAPPINGS"
- fi
REDIRECT "/cards/?o=${order}&f=${filter}"
;;
esac
- # Copyright 2014 - 2019 Paul Hänsch
+ # Copyright 2014 - 2019, 2021 Paul Hänsch
#
# This file is part of Confetti.
#
# You should have received a copy of the GNU Affero General Public License
# along with Confetti. If not, see <http://www.gnu.org/licenses/>.
-list_categories() {
- grep -vxE '^[ ]*$' "${_DATA}/mappings/categories"
-}
-
-list_courses() {
- local file name cachefile="${_DATA}/cache/courses.ui.cache"
- if [ $cachefile -nt "${_DATA}/ical" ]; then
- cat "$cachefile"
- else
- for file in "$_DATA/ical"/*.ics; do
- name="$(pdi_value "$(pdi_load "$file")" SUMMARY |HTML)"
- printf '%s %s\n' "$file" "$name"
- done \
- | sort -k2 |tee "$cachefile"
- fi
-}
-
w_filter_item() {
n=$3
cat <<EOF
[fieldset .item
[legend $(l10n filter_item):]
- $(for field in any name street zip TEL BDAY CATEGORIES course; do
- printf '[input id="%s%i" type="radio" name="filter_type%i" value="%s" %s][label for="%s%i" %s ]' \
+ $(for field in any name street zip TEL BDAY; do
+ printf '[input id="%s%i" type="radio" name="filter_type%i" value="%s" %s]
+ [label for="%s%i" %s ]' \
"$field" "$n" "$n" "$field" "$([ "$1" = "$field" ] && printf checked )" \
"$field" "$n" "$(l10n filter_$field)"
done)
- [input type="text" name="filter_text$n" value="$([ "$1" = CATEGORIES -o "$1" = course ] || HTML "$2")" placeholder="$(l10n filter_placeholder)"]
- [fieldset .categories
- $(list_categories | while read cat; do
- printf '[label [checkbox "filter_cat%i" "|%s" %s] %s ] ' \
- "$n" "$(HTML "$cat")" \
- "$(printf %s "$cat" |grep -qxEe "$2" && printf checked )" \
- "$(HTML "$cat")"
- done)
- [a href="/categories/" $(l10n edit_categories)]
- ]
- [fieldset .courses
- $(list_courses | while read course coursename; do
- printf '[label [checkbox "filter_course%i" "|%s" %s] %s ] ' \
- "$n" "$(HTML "${course##*/}")" \
- "$(printf %s "${course##*/}" |grep -qxEe "$2" && printf checked )" \
- "$coursename"
- done)
- ]
+ [input type="text" name="filter_text$n" value="$([ "$1" = CATEGORIES ] || HTML "$2")" placeholder="$(l10n filter_placeholder)"]
]
EOF
}
w_filter_item "${fil%%:*}" "${fil#*:}" $n
n=$((n + 1))
done
- w_filter_item any '' $n
+ [ "$n" -eq 0 -o "$(GET newfilter)" ] && w_filter_item any '' $n
)
-
+ [button type="submit" name="choice" value="new_filter" $(l10n filter_more)]
[fieldset class="order"
[legend $(l10n filter_order):]
- [label [radio "order" "firstname" $( [ "$order" = firstname ] && printf checked )] $(l10n filter_firstname)]
[label [radio "order" "lastname" $( [ "$order" = lastname ] && printf checked )] $(l10n filter_lastname)]
+ [label [radio "order" "firstname" $( [ "$order" = firstname ] && printf checked )] $(l10n filter_firstname)]
[label [radio "order" "bdate" $( [ "$order" = bdate ] && printf checked )] $(l10n filter_bdate)]
]
- [button type="submit" name="choice" value="new_filter" $(l10n filter_apply)]
+ [button type="submit" name="choice" value="filter" $(l10n filter_apply)]
[button type="submit" name="choice" value="del_filter" $(l10n filter_cancel)]
+ [button type="submit" name="choice" value="export_csv" $(l10n export_csv)]
]
EOF
}
-# listcards |grep ${edit:+-v} "$edit" \
-# | while read card; do
-# "${_EXEC}"/cgilite/html-sh.sed <<-ENDCARD
-# [div #${card} .card
-# $(view_card "$card")[!--
-# --][div .control
-# [a "?action=edit_card&card=${card}" .item $(l10n edit)]
-# [a "?action=export_vcard&card=${card}".item $(l10n vcf_export)]
-# ${profile_medical:+[a "?action=new_prescription&client=${card}" .item $(l10n new_prescription)]}
-# ]]
-# ENDCARD
-# done
-
-#!/bin/sh
-
card_item(){
local card="$1"
local item cnt c
cnt="$(pdi_count "$card" "$item")"
case $item in
- FN) printf '[h2 .item .FN . %s]' "$(pdi_value "$card" FN |pdi_unescape |HTML)"
+ FN) printf '[h2 .item .FN . %s]' "$(pdi_value "$card" FN |unescape |HTML)"
;;
GENDER) printf '[span .item .GENDER . %s]' "$(pdi_value "$card" GENDER |l10n)"
;;
NICKNAME) seq 1 $cnt |while read c; do
- printf '[span .item .NICKNAME aka. "%s"]' \
- "$(pdi_value "$card" NICKNAME $c |pdi_unescape |HTML)"
+ printf '[span .item .NICKNAME . aka. "%s"]' \
+ "$(pdi_value "$card" NICKNAME $c |unescape |HTML)"
done
;;
X-ZACK-JOINDATE|X-ZACK-LEAVEDATE) if [ $cnt -gt 0 ]; then
[ $cnt -gt 0 ] && printf '[h3 %s]' "$(l10n EMAIL)"
seq 1 $cnt |while read c; do
printf '[a .item .EMAIL href="mailto:%s" . %s]' \
- "$(pdi_value "$card" EMAIL $c |pdi_unescape |HTML)" \
- "$(pdi_value "$card" EMAIL $c |pdi_unescape |HTML)"
+ "$(pdi_value "$card" EMAIL $c |unescape |HTML)" \
+ "$(pdi_value "$card" EMAIL $c |unescape |HTML)"
done
;;
TEL)
[ "$teltype" ] \
&& printf '[span .item .TEL [span .type . %s:] %s]' \
"$(l10n "TYPE=$teltype" |HTML)" \
- "$(pdi_value "$card" TEL $c |pdi_unescape |HTML)" \
+ "$(pdi_value "$card" TEL $c |unescape |HTML)" \
|| printf '[span .item .TEL . %s]' \
- "$(pdi_value "$card" TEL $c |pdi_unescape |HTML)"
+ "$(pdi_value "$card" TEL $c |unescape |HTML)"
done
;;
- ' "$(pdi_unescape "$hi_name" |HTML)" \
- "$(l10n hi_number)" "$(pdi_unescape "$hi_number" |HTML)" \
- "$(l10n hi_status)" "$(pdi_unescape "$hi_status" |HTML)"
+ X-HEALTH-INSURANCE)
+ [ $cnt -gt 0 ] && printf '[h3 %s]' "$(l10n X-HEALTH-INSURANCE)"
+ seq 1 $cnt |while read c; do
+ IFS=\; read -r hi_name hi_number hi_status <<-EOF
+ $(pdi_value "$card" X-HEALTH-INSURANCE $c)
+ EOF
+ printf '[span .item .hi_company . %s]
+ [span .item .hi_number [label %s:] %s]
+ [span .item .hi_status [label %s:] %s]
++ ' "$(unescape "$hi_name" |HTML)" \
++ "$(l10n hi_number)" "$(unescape "$hi_number" |HTML)" \
++ "$(l10n hi_status)" "$(unescape "$hi_status" |HTML)"
+ done
+ ;;
+ therapies)
+ client="$(pdi_value "$card" UID)"
+ printf '[h3 %s]' "$(l10n therapies)"
+ (cd "$_DATA/therapies/"; printf '%s\n' "${client}".*.tpy) \
+ | while read tpyfile; do
+ [ "$tpyfile" = "${client}.*.tpy" ] \
+ && printf '[a .item .therapy href="/therapies/%s/new" . +]' "${client}" \
+ && break
+ tpy="${tpyfile%.tpy}";
+ tpydates="$(sed -En 's;^session[0-9]+_date:;;p;' "$_DATA/therapies/$tpyfile" \
+ | sort \
+ | sed -E ':X;N;$!bX; s;^[\n ]+;;; s;[\n ]+$;;; s;(\n.*\n|\n); - ;;'
+ )"
+ printf '[a .item .therapy href="/therapies/%s" . %s] ' \
+ "${tpy%.*}/${tpy#*.}" "$(HTML "${tpydates:--}")"
+ done |sort -n
+ ;;
*)[ $cnt -gt 0 ] && printf '[h3 %s]' "$(l10n "$item")"
+ shy="$(printf '\302\255')"
seq 1 $cnt |while read c; do
printf '[span .item .%s . %s]' "$item" \
- "$(pdi_value "$card" "$item" $c |sed -r "s;(straße|weg|damm|allee|ufer);${shy}\1;g" |pdi_unescape |HTML)"
- "$(pdi_value "$card" "$item" $c |unescape |HTML)"
++ "$(pdi_value "$card" "$item" $c |sed -r "s;(straße|weg|damm|allee|ufer);${shy}\1;g" |unescape |HTML)"
done
;;
esac
$N
EOF
else
- N="$(pdi_value "$card" FN |pdi_unescape)"
- n1="${N%%[a-z]*}" n1="${N#$n1}"
- [ "$n1" ] || n1="${N##* }"
+ N="$(pdi_value "$card" FN |unescape)"
+ n1="${N##* }"
n2="${N%$n1}"
fi
printf '
[input .item .N name="5N" placeholder="%s" value="%s"]
' "$(l10n "$item")" \
"$(l10n n_pre)" "$(HTML "$n4")" \
- "$(l10n n_first)" "$(HTML "${n2}${n3:+ }${n3}")" \
+ "$(l10n n_first)" "$(HTML "${n2}$([ "$n2" -a "$n3" ] && printf ' ')${n3}")" \
"$(l10n n_last)" "$(HTML "$n1")" \
"$(l10n n_post)" "$(HTML "$n5")"
;;
printf '[checkbox "%s_delete_%i" "true" .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)"
+ "$item" "$item" "$(pdi_value "$card" "$item" $c |pdi_unescape |HTML)"
done
printf '[button type="submit" name="action" value="addfield %s" %s ]' "$item" "$(l10n edit_addfield)"
;;
"$([ "$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")"
+ "$item" "$item" "$(pdi_value "$card" "$item" $c |pdi_unescape |HTML)" "$(l10n "$item")"
done
printf '[button type="submit" name="action" value="addfield %s" %s ]' "$item" "$(l10n edit_addfield)"
;;
+ X-HEALTH-INSURANCE)
+ printf '[h3 %s]' "$(l10n "$item")"
+ seq 1 $cnt |while read c; do
+ # printf '[checkbox "%s_delete_%i" "true" .delete #%s_delete_%i][label for="%s_delete_%i" %s]' \
+ # "$item" $c "$item" $c "$item" $c "$(l10n delete)"
+ IFS=\; read -r hi_name hi_number hi_status <<-EOF
+ $(pdi_value "$card" X-HEALTH-INSURANCE $c)
+ EOF
+ cat <<-EOF
+ [input type="radio" name="$item" value="list" #hi_select_list checked]<!--
+ -->[label for="hi_select_list" $(l10n hi_from_list)]<!--
+ -->[input type="radio" name="$item" value="other" #hi_other checked]<!--
+ -->[label for="hi_other" $(l10n hi_other)]<!--
+ -->[select class="item" name="hi_company"
+ [option value="" disabled="disabled" $(selected "${hi_name}" "") . $(l10n hi_company)]
+ $(list_hi_companies |while read f; do
+ printf '[option value="%s" %s . %s]' "$(pdi_unescape "$f" |HTML)" \
+ "$(selected "$f" "$hi_name")" \
+ "$(pdi_unescape "$f" |HTML)"
+ done)
+ ]
+ [input type="text" name="hi_other" value="$hi_name" placeholder="$(l10n hi_company)"]
+ [input name="hi_number" value="$(pdi_unescape "$hi_number" |HTML)" placeholder="$(l10n hi_number)"]
+ [input name="hi_status" value="$(pdi_unescape "$hi_status" |HTML)" placeholder="$(l10n hi_status)"]
+ EOF
+ done
+ ;;
*)printf '[h3 %s]' "$(l10n "$item")"
seq 1 $cnt |while read c; do
printf '[checkbox "%s_delete_%i" "true" .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")"
+ "$item" "$item" "$(pdi_value "$card" "$item" $c |pdi_unescape |HTML)" "$(l10n "$item")"
done
printf '[button type="submit" name="action" value="addfield %s" %s ]' "$item" "$(l10n edit_addfield)"
;;
for n in "$@"; do case ${n%%=*} in
data) _DATA="${n#data=}";;
exec) _EXEC="${n#exec=}";;
- noerr) exec 2>&-;;
+ debug) DEBUG="${n#debug=}";;
esac; done
- [ -z "${_EXEC%/}" ] && _EXEC="$(realpath "${0%/*}")" || _EXEC="${_EXEC%/}"
- [ -z "${_DATA%/}" ] && _DATA=. || _DATA="${_DATA%/}"
+ [ ! "${_EXEC%/}" ] && _EXEC="$(realpath "${0%/*}")" || _EXEC="${_EXEC%/}"
+ [ ! "${_DATA%/}" ] && _DATA=. || _DATA="${_DATA%/}"
+ [ "$DEBUG" ] && exec 2>>"$DEBUG"
+
+ mkdir -p "${_DATA}/cache" "${_DATA}/mappings" "${_DATA}/export" "${_DATA}/lock" "${_DATA}/ical" "${_DATA}/vcard"
+
+ debug() {
+ local dbg=/dev/stderr
+ if [ ! "$DEBUG" ]; then
+ [ "$#" -gt 0 ] && : || cat;
+ elif [ "$#" -gt 0 ]; then
+ printf '%s\n' "$@" >>"$dbg"
+ else
+ tee -a "$dbg"
+ fi
+ }
+debug() {
+ local dbg=/dev/stderr
+ if [ ! "$DEBUG" ]; then
+ [ "$#" -gt 0 ] && : || cat;
+ elif [ "$#" -gt 0 ]; then
+ printf '%s\n' "$@" >>"$dbg"
+ else
+ tee -a "$dbg"
+ fi
+}
+
. "$_EXEC/cgilite/cgilite.sh"
. "$_EXEC/cgilite/session.sh"
+ . "$_EXEC/l10n.sh"
+
_PATH="$(PATH "/${PATH_INFO}")"
ACTION="$(GET a)"
printf 'Content-Type: text/html; charset=utf-8\r\n\r\n'
{ printf '
[html [head
- [title Confetti]
+ [title Lobster]
[meta name="viewport" content="width=device-width"]
[link rel="stylesheet" type="text/css" href="/style.css"]
'
printf '
] [body #top class="%s"
' "$class"
+ printf '[ul .menu [li [a "/cards/" . %s]][li [a "/courses/" . %s]]]' "$(l10n cards)" "$(l10n courses)"
+ [ "$message" ] && printf '[p #message\n%s\n]' "$(l10n "$message")"
cat
- [ "$message" ] && printf '[p #message\n%s\n]' $(l10n "$message")
printf '] ]'
} \
| "${_EXEC}/cgilite/html-sh.sed"
topdir="${_PATH#/}"
topdir="/${topdir%%/*}"
- if [ "${_PATH}" = / ]; then
- REDIRECT /cards/
- elif [ -d "${_EXEC}/${_PATH}" -a -x "${_EXEC}/${_PATH}/index.cgi" ]; then
- . "${_EXEC}/${_PATH}/index.cgi"
- elif [ ! -d "${_EXEC}/${_PATH}" -a -x "${_EXEC}/${_PATH}" ]; then
- . "${_EXEC}/${_PATH}"
- elif [ ! -x "${_EXEC}/${_PATH}" -a -r "${_EXEC}/${_PATH}" ]; then
- . "$_EXEC/cgilite/file.sh"
- FILE "${_EXEC}/${_PATH}"
- elif [ -d "${_EXEC}/${topdir}" -a -x "${_EXEC}/${topdir}/index.cgi" ]; then
- . "${_EXEC}/${topdir}/index.cgi"
- else
- printf 'Status: 404 Not Found\r\nContent-Length: 0\r\n\r\n'
- fi
+ case ${_PATH} in
+ /) REDIRECT /cards/
+ ;;
- /export/*.pdf) . "$_EXEC/cgilite/file.sh"
- FILE "${_DATA}/${_PATH}" "application/pdf"
- ;;
- /export/*) . "$_EXEC/cgilite/file.sh"
- FILE "${_DATA}/${_PATH}"
- ;;
++# /export/*.pdf) . "$_EXEC/cgilite/file.sh"
++# FILE "${_DATA}/${_PATH}" "application/pdf"
++# ;;
++# /export/*) . "$_EXEC/cgilite/file.sh"
++# FILE "${_DATA}/${_PATH}"
++# ;;
+ *)
+ if [ -d "${_EXEC}/${_PATH}" -a -x "${_EXEC}/${_PATH}/index.cgi" ]; then
+ . "${_EXEC}/${_PATH}/index.cgi"
+ elif [ -f "${_EXEC}/${_PATH}" -a -x "${_EXEC}/${_PATH}" ]; then
+ . "${_EXEC}/${_PATH}"
+ elif [ -f "${_EXEC}/${_PATH}" -a -r "${_EXEC}/${_PATH}" ]; then
+ . "$_EXEC/cgilite/file.sh"
+ FILE "${_EXEC}/${_PATH}"
+ elif [ -d "${_EXEC}/${topdir}" -a -x "${_EXEC}/${topdir}/index.cgi" ]; then
+ . "${_EXEC}/${topdir}/index.cgi"
+ else
+ printf '%s\r\n' 'Status: 404 Not Found' 'Content-Length: 0' ''
+ fi
+ ;;
+ esac
BR='
'
+ unescape() {
+ local unescape='s;(^(\\\\)*|[^\\](\\\\)*)\\n;\1\n;g; s;\\(.);\1;g'
+ if [ $# -eq 0 ]; then
+ sed -E "$unescape"
+ else
+ printf %s "$*" \
+ | sed -E "$unescape"
+ fi
+ }
+
pdi_load() {
# normalise PDI file for processing with pdi_* functions
# functions in this library can only be applied to normalised data
# Usage example:
# data="$(pdi_load file.vcf)"
- sed -En '
+ sed -srn '
# === Read entire file into buffer ===
:X $bY; N; bX; :Y s;^.*$;\n&\n;;
# === Update obsolete LABEL property ===
s;\nLABEL((\;[A-Za-z0-9-]+|\;[A-Za-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):(.*)\n;\nADR\1\;LABEL="\5":\n;g;
- p;' "$1"
+ p;' "$@"
}
+pdi_escape(){
+ local in out=''
+ for in in "$@"; do
+ out="${out}${out:+;}"
+ while [ "$in" ]; do case $in in
+ \\*) out="${out}\\\\"; in="${in#\\}" ;;
+ ,*) out="${out}\\,"; in="${in#,}" ;;
+ \;*) out="${out}\\;"; in="${in#;}" ;;
+ "$BR"*) out="${out}\\n"; in="${in#${BR}}" ;;
+ *) out="${out}${in%%[\\,;${BR}]*}"; in="${in#"${in%%[\\,;${BR}]*}"}" ;;
+ esac; done
+ done
+ printf '%s\n' "$out"
+}
+
+pdi_unescape(){
+ local in out=''
+ [ $# -gt 0 ] && in="$*" || in="$(cat)"
+ while [ "$in" ]; do case $in in
+ \\\\*) out="${out}\\"; in="${in#\\\\}" ;;
+ \\n*) out="${out}${BR}"; in="${in#\\n}" ;;
+ \\*) in="${in#\\}" ;;
+ *) out="${out}${in%%\\*}"; in="${in#"${in%%\\*}"}" ;;
+ esac; done
+ printf '%s\n' "$out"
+}
+
pdi_count(){
local card="$1" name="$2" rc='' cnt=0
while rc="${card#*${BR}${name};}"; do