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
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
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 "Anmelde­datum";;
X-ZACK-LEAVEDATE) printf %s "Abmelde­datum";;
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
[div .item .delete label="$(l10n edit_delete)"
[input type="checkbox" #delete]
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
[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;'
while [ "$filter" ]; do
f="${filter%%^*}" filter="${filter#*^}"
+ debug "Filter: $f"
case $f in
'') break
;;
- COURSE:*) fatt="${fatt}${fatt:+ }${f#*:}"
- ;;
ANY:*) fex="/\n.*(\;[^:]*)?:[^\n]*(${f#*:})[^\n]*\r?\n/{${fex}}"
;;
NAME:*) fex="/\n(N|FN|NICKNAME)(\;[^:]*)?:[^\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"
}
. "$_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)"
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 "$tempfile")"
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)
- 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
# 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
}
[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="filter" $(l10n filter_apply)]
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
"$(pdi_value "$card" TEL $c |unescape |HTML)"
done
;;
+ 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 |unescape |HTML)"
+ "$(pdi_value "$card" "$item" $c |sed -r "s;(straße|weg|damm|allee|ufer);${shy}\1;g" |unescape |HTML)"
done
;;
esac
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)"
;;
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"
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"]
'
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"
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
--- /dev/null
+var button = document.querySelector('#savebutton');
+var formdata_old = '';
+var formdata = '';
+
+function postsubmit(){
+ if ( this.status == 200 ) {
+ document.querySelector('#report input[name="tid"]').setAttribute('value', this.response);
+ console.log('successful auto submit of form data');
+ button.setAttribute('style', 'display: none;');
+ } else {
+ console.log('!!! Error response while auto submitting form data');
+ button.setAttribute('style', 'display: block;');
+ }
+}
+function failsubmit(){
+ console.log('!!! Timeout while auto submitting form data');
+ button.setAttribute('style', 'display: block;');
+}
+
+function formencode(fd){
+ var send;
+ send='autosubmit=true';
+ for (var tup of fd.entries()){
+ send += '&' + encodeURIComponent(tup[0]) + '=' + encodeURIComponent(tup[1]);
+ }
+ return send;
+}
+
+function formsend(){
+ var request = new XMLHttpRequest();
+ request.open('post', '/therapies/update_therapy.sh');
+ request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+ request.timeout = 5000;
+ request.onload = postsubmit;
+ request.ontimeout = failsubmit;
+ request.onerror = failsubmit;
+ request.onabort = failsubmit;
+
+ formdata = formencode(new FormData(document.querySelector('#report')));
+
+ if ( ! (formdata == formdata_old) ) {
+ console.log( 'send' );
+ request.send( formdata );
+ formdata_old = formdata;
+ }
+}
+
+formdata_old = formencode(new FormData(document.querySelector('#report')));
+button.setAttribute('style', 'display: none;');
+setInterval(formsend, 500);
--- /dev/null
+#!/bin/sh
+
+# Copyright 2016, 2020 Paul Hänsch
+#
+# This file is part of Lobster.
+#
+# Lobster is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Lobster is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Lobster. If not, see <http://www.gnu.org/licenses/>.
+
+case "$_PATH" in
+ /therapies/therapy.css)
+ . $_EXEC/cgilite/file.sh
+ FILE $_EXEC/therapies/therapy.css
+ return 0
+ ;;
+ /therapies/*.*_session*.png)
+ if [ -r "$_DATA/$_PATH" ]; then
+ . $_EXEC/cgilite/file.sh
+ FILE "$_DATA/$_PATH"
+ fi
+ return 0
+ ;;
+ /therapies/*/new)
+ card="${_PATH#/therapies/}"
+ card="${card%/new}"
+ uid="$(timeid)$(randomid)"
+ if [ -f "${_DATA}/vcard/${card}.vcf" ]; then
+ touch "${_DATA}/therapies/${card}.${uid}.tpy"
+ rm -f "${_DATA}/cache/${card}.vcf.cache"
+ REDIRECT "/therapies/${card}/${uid}"
+ fi
+ return 0
+ ;;
+esac
+
+. $_EXEC/pdiread.sh
+. $_EXEC/therapies/l10n.sh
+
+id="${_PATH#/therapies/}"
+id="${id%/*}.${id#*/}"
+
+read junkx junky bg_dim junkz <<-E_READ
+ $(identify "$_EXEC/therapies/therapy_background.png")
+E_READ
+
+vcffile="${_DATA}/vcard/${id%.*}.vcf"
+mpxfile="${_DATA}/prescriptions/${id}.mpx"
+tpyfile="${_DATA}/therapies/${id}.tpy"
+
+vcf="$(pdi_load "$vcffile")"
+mpx="$([ -f "$mpxfile" ] && sed '1s;^;\n;; s/:/;:/' "$mpxfile")"
+tpy="$(sed '1s;^;\n;; s/:/;:/' "$tpyfile")"
+
+VCF(){ pdi_value "$vcf" "$@"; }
+MPX(){ pdi_value "$mpx" "$@"; }
+TPY(){ pdi_value "$tpy" "$@" >/dev/null && pdi_value "$tpy" "$@" |pdi_unescape; }
+
+. $_EXEC/therapies/page.sh \
+| yield_page therapy /therapies/therapy.css
--- /dev/null
+# Copyright 2016, 2020 Paul Hänsch
+#
+# This file is part of Confetti.
+#
+# Confetti is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Confetti is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Confetti. If not, see <http://www.gnu.org/licenses/>.
+
+#. $_EXEC/templates/text_prescriptions.sh
+l10n(){
+ local word
+ [ $# -eq 0 ] && read -r word || word="$1"
+ case $word in
+ therapy_prescription) printf '%s\n' "Heil­mit­tel­ver­ord­nung";;
+ prescriptions_current) printf '%s\n' "Aktuelle Verordnungen";;
+ prescriptions_past) printf '%s\n' "Frühere Verordnungen";;
+ newprescription) printf '%s\n' "Neue Verordnung";;
+ date) printf '%s\n' "Datum";;
+ name) printf '%s\n' "Name d. Versicherten";;
+ bday) printf '%s\n' "geb. am";;
+ addcontrib) printf '%s\n' "Zuzahlung";;
+ contribconfirm) printf '%s\n' "Zuzahlung erfolgt am...";;
+ contribreceipt) printf '%s\n' "Quit­tung heraus­ge­ge­ben";;
+ prescreviewed) printf '%s\n' "Verordnung geprüft";;
+ prescreview) printf '%s\n' "Verordnung prüfen!";;
+ quantity) printf '%s\n' "Ver­ord­nungs­men­ge";;
+ remidy) printf '%s\n' "Heil­mit­tel nach Maß­ga­be des Ka­ta­lo­ges";;
+ prescfirst) printf '%s\n' "Erst­ver­ord­nung";;
+ prescfollow1) printf '%s\n' "1. Folge-­VO";;
+ prescfollow2) printf '%s\n' "2. Folge-­VO";;
+ prescother) printf '%s\n' "VO außer­halb des Re­gel­falls";;
+ presccontinual) printf '%s\n' "Lang­frist­ver­ord­nung";;
+ grouptherapy) printf '%s\n' "Grup­pen­the­ra­pie";;
+ housecall) printf '%s\n' "Haus­be­such";;
+ report) printf '%s\n' "The­ra­pie­be­richt";;
+ indicator) printf '%s\n' "In­di­ka­tions­schlüssel";;
+ icd10) printf '%s\n' "ICD-10-Code";;
+ indicator_reading) printf '%s\n' "Befund Beschreibung";;
+ insurance) printf '%s\n' "Krankenkasse bzw. Kostenträger";;
+ prescription_by_catalogue) printf '%s\n' "Verordnung nach Maßgabe des Kataloges (Regelfall)";;
+ therapy_start) printf '%s\n' "Be­hand­lungs­be­ginn spä­test. am";;
+ quantity_weekly) printf '%s\n' "An­zahl pro Wo­che";;
+ save) printf '%s\n' "Speichern";;
+ cancel) printf '%s\n' "Abbrechen";;
+ delete) printf '%s\n' "Löschen";;
+
+ therapy) printf '%s\n' "Therapie";;
+ therapies) printf '%s\n' "Therapien";;
+
+ prescriptionlist) printf '%s\n' "Zur Verordnungsliste";;
+ delete_session) printf '%s\n' "Therapiesitzung entfernen";;
+ therapist) printf '%s\n' "Therapeut";;
+ number) printf '%s\n' "Nr.";;
+ signature) printf '%s\n' "Un­ter­schrift";;
+ weekly) printf '%s\n' "p. Woche";;
+ notes) printf '%s\n' "Notizen";;
+ trailsave) printf '%s\n' "Speichern für weitere Felder";;
+
+ *) HTML "$word";;
+ esac
+}
--- /dev/null
+# Copyright 2016, 2017, 2020 Paul Hänsch
+#
+# This file is part of Lobster.
+#
+# Confetti is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Lobster is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Lobster. If not, see <http://www.gnu.org/licenses/>.
+
+t_session_note(){
+ session_n="$1"
+ note_n="$2"
+
+ color=session${session_n}_note${note_n}_color
+
+ if [ "$note_n" -eq 1 -o "$(TPY "session${session_n}_note${note_n}")" ]; then
+ printf '[input type="checkbox" .trailbtn checked="checked"]'
+ else
+ printf '[input type="checkbox" .trailbtn]'
+ fi
+
+ check="$(TPY "$color" |grep -xE -m1 '#(888|00A|0A0|0AA|A00|A0A|AA0)' || printf '#FFF')"
+ cat <<-EOF
+ [fieldset .note .trailbox
+ [radio "$color" "#888" .color #${color}_000 $(checked "$check" '#888') ][label for=${color}_000]
+ [radio "$color" "#00A" .color #${color}_001 $(checked "$check" '#00A') ][label for=${color}_001]
+ [radio "$color" "#0A0" .color #${color}_010 $(checked "$check" '#0A0') ][label for=${color}_010]
+ [radio "$color" "#0AA" .color #${color}_011 $(checked "$check" '#0AA') ][label for=${color}_011]
+ [radio "$color" "#A00" .color #${color}_100 $(checked "$check" '#A00') ][label for=${color}_100]
+ [radio "$color" "#A0A" .color #${color}_101 $(checked "$check" '#A0A') ][label for=${color}_101]
+ [radio "$color" "#AA0" .color #${color}_110 $(checked "$check" '#AA0') ][label for=${color}_110]
+ [radio "$color" "#FFF" .color #${color}_111 $(checked "$check" '#FFF') ][label for=${color}_111]
+ [textarea name="session${session_n}_note${note_n}" . $(TPY "session${session_n}_note${note_n}" |HTML)]
+ ]
+ EOF
+}
+
+therapy_sessions(){
+ n=1; while [ "$(TPY session$n)" ]; do n=$((n + 1)); done
+
+ sid=session$n
+ cat <<-EOF
+ [fieldset .tab
+ [submit "new_session" "$sid" .no . +]
+ [input .date name="${sid}_date" value="" placeholder=$(l10n date)]
+ [input .therapist name="${sid}_therapist" value="" placeholder=$(l10n therapist)]
+ [span .signature]
+ [hidden "${sid}_note1" ""]
+ ]
+ EOF
+
+ for n in $(seq $((n - 1)) -1 1); do
+ session_n="$n"
+ sid=session${session_n}
+
+ cat <<-EOF
+ [hidden "$sid" "exists"]
+ [checkbox "${sid}_open" "checked" #${sid}_open .tab $(checked "$(TPY "${sid}_open")" checked)]
+ [label .tab for="${sid}_open"
+ [span .no ${session_n}.]
+ [span .date . $(TPY "${sid}_date" |HTML)]
+ [input .date name="${sid}_date" value="$(TPY "${sid}_date" |HTML)" placeholder="$(l10n date)"]
+ [span .therapist . $(TPY "${sid}_therapist" |HTML)]
+ [input .therapist name="${sid}_therapist" value="$(TPY "${sid}_therapist" |HTML)" placeholder="$(l10n therapist)"]
+ [span .signature [checkbox "${sid}_sigset" "pos" $(checked "$(TPY "${sid}_sigset")" "pos")]]
+ ]
+ [div .tab
+ [img .dotmark .ov src="/therapies/${id}_${sid}.png?${_DATE}" alt=""]
+ $(n=1; while TPY "session${session_n}_note${n}" >/dev/null; do
+ [ "$(TPY "session${session_n}_note${n}")" ] && x=$n
+ n=$(($n + 1))
+ done
+ for n in $(seq 1 $((${x:-0} + 3)) ); do
+ t_session_note $session_n $n
+ done
+ )
+ [button type="submit" .trailbtn $(l10n trailbtn)]
+ [button type="submit" name=delete_session value="$session_n" .delete $(l10n delete_session)]
+ ]
+ EOF
+ done
+}
+
+cat <<EOF
+[h1 $(l10n therapy)]
+
+[div .patient
+ [h2 . ⬅ $(VCF FN |HTML)]
+]
+
+[div .therapies
+ [h2 $(l10n therapies)]
+ $(
+ (cd "$_DATA/therapies/"; printf '%s\n' "${id%%.*}".*.tpy) \
+ | while read tpyfile; do
+ [ "$tpyfile" = "${id%%.*}.*.tpy" ] && 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); - ;;'
+ )"
+ if [ "${tpy%.*}.${tpy#*.}" = "${id}" ]; then
+ printf '[a .item .therapy .current href="/therapies/%s" . %s] ' \
+ "${tpy%.*}/${tpy#*.}" "$(HTML "${tpydates:--}")"
+ else
+ printf '[a .item .therapy href="/therapies/%s" . %s] ' \
+ "${tpy%.*}/${tpy#*.}" "$(HTML "${tpydates:--}")"
+ fi
+ done |sort -n
+ )
+ [!-- a .item .therapy href="/therapies/${id%%.*}/new" . + --]
+]
+EOF
+
+if [ "$mpx" ]; then
+ printf '[div .prescription [h2 %s]' "$(l10n therapy_prescription)"
+
+ printf '[ul'
+ for n in '' 0 1 2 3 4 5 6 7 8 9 10; do
+ remidy="$(MPX remidy$n)"
+ quantity="$(MPX quantity$n)"
+ quantity_weekly="$(MPX quantity_weekly$n)"
+
+ if [ "$remidy" -a "$quantity_weekly" ]; then
+ printf '[li %s %s %s]' "$(HTML "$quantity")" "$(HTML "$remidy")" "$(HTML "$quantity_weekly") $(l10n weekly)"
+ elif [ "$remidy" ]; then
+ printf '[li %s %s]' "$(HTML "$quantity")" "$(HTML "$remidy")"
+ fi
+ done
+ printf ']'
+
+ for field in indicator icd10; do
+ val="$(MPX "$field")"
+ [ "$val" ] && printf '[span .%s [label . %s:]%s]' "$field" "$(l10n "$field")" "$(HTML "$val")"
+ done
+
+ if [ "$(MPX indicator_reading)" ]; then
+ printf '[h3 %s][p . %s]' \
+ "$(l10n indicator_reading)" "$(MPX indicator_reading |HTML)"
+ fi
+
+ printf ']'
+fi
+
+cat <<EOF
+[form #report method=POST action="/therapies/update_therapy.sh"
+ [hidden "id" "$id"][hidden "tid" "$(transid "$tpyfile")"]
+
+ [button #backbutton type=submit name="vcfreturn" value="true" ⬅ $(VCF FN |HTML)]
+
+ [input .stickynote type=checkbox name=c_stickynote #show_stickynote]
+ [fieldset .stickynote
+ [label for="show_stickynote" $(l10n notes)]
+ [h2 $(l10n notes)]
+ [textarea name=stickynote . $(TPY stickynote |HTML)]
+ [button type=submit $(l10n save)]
+ ]
+EOF
+
+# cat <<EOF
+# [input .stickynote type=checkbox name=c_timesheet #show_timesheet]
+# [fieldset .stickynote
+# [label for="show_timesheet" $(l10n timesheet)]
+# [h2 $(l10n timesheet)]
+# [table [thead [tr
+# [th $(l10n time_goal)][th $(l10n time_actual)][th $(l10n time_difference)]
+# ]][tbody
+# $(for n in '' 0 1 2 3 4 5 6 7 8 9 10; do
+# tsgoal="$(TPY tsgoal$n |grep -m1 -xE '[0-9]+')"
+# tsactual="$(TPY tsactual$n |grep -m1 -xE '[0-9]+')"
+# printf '[tr [td [input type=number name=tsgoal value="%s"]][td [input type=number name=tsactual value="%s"]][td %s]]' \
+# "$tsgoal" "$tsactual" "$(( ${tsgoal:-0} - ${tsactual:-0} ))"
+# done)
+# ]]
+# [button type=submit $(l10n save)]
+# ]
+# EOF
+
+cat <<EOF
+ [label .tab .heading
+ [span .no $(l10n number)][span .date $(l10n date)][span .therapist $(l10n therapist)][span .signature $(l10n signature)]
+ ]
+EOF
+
+therapy_sessions
+
+## ==== Drawing canvas ==== ##
+### ====================== ###
+
+penwidth="$(TPY penwidth |grep -xE -m1 '(4|12|36)' || printf '4')"
+color="$(TPY color |grep -xE -m1 '#(000|00A|0A0|0AA|A00|A0A|AA0|FFF)' || printf '#000')"
+cat <<EOF
+ [fieldset .penwidth
+ [radio "penwidth" "4" #pw1 $(checked "$penwidth" 4) ][label for="pw2"]
+ [radio "penwidth" "12" #pw2 $(checked "$penwidth" 12)][label for="pw3"]
+ [radio "penwidth" "36" #pw3 $(checked "$penwidth" 36)][label for="pw1"]
+ ]
+ [fieldset .color
+ [radio "color" "#000" .color #c000 $(checked "$color" '#000') ][label for=c000 ]
+ [radio "color" "#00A" .color #c001 $(checked "$color" '#00A') ][label for=c001 ]
+ [radio "color" "#0A0" .color #c010 $(checked "$color" '#0A0') ][label for=c010 ]
+ [radio "color" "#0AA" .color #c011 $(checked "$color" '#0AA') ][label for=c011 ]
+ [radio "color" "#A00" .color #c100 $(checked "$color" '#A00') ][label for=c100 ]
+ [radio "color" "#A0A" .color #c101 $(checked "$color" '#A0A') ][label for=c101 ]
+ [radio "color" "#AA0" .color #c110 $(checked "$color" '#AA0') ][label for=c110 ]
+ [radio "color" "#FFF" .color #c111 $(checked "$color" '#FFF') ][label for=c111 ]
+ ]
+ [img .dotmark .bg src="/therapies/therapy_background.png" alt="WARNING: Missing background image!"]
+ [canvas #canvas .dotmark .ov width="${bg_dim%x*}" height="${bg_dim#*x}" ]
+ [input type=hidden #image_serialize name=imagedata value=""]
+
+ [input type=hidden name=formend value=formend]
+ [button #savebutton type=submit $(l10n save)]
+]
+
+[span #jsdebug style="display: none; position: fixed; right:0; bottom:0" Debug]
+
+[script type="text/javascript" src="/therapies/therapy_draw.js"]
+[!-- script type="text/javascript" src="/therapies/autosave.js" --]
+EOF
background-color: #FEE;
}
+form > button#backbutton {
+ position: absolute;
+ top: 2em;
+ left: 2%;
+ background: transparent;
+ border: none;
+ padding: 0;
+ margin: 0;
+}
+
+
input.tab { display: none; }
input.tab + label.tab { display: block; }
input.tab + label.tab::before { content: '\25b8 \00a0'; float: left;}
input.color[value="#FFF"] + label { background-color: #FFF;}
h1, label.tab, div.tab, fieldset.tab,
-div.patient, div.prescription {
+div.patient, div.prescription, div.therapies {
display: block;
width: 96%;
margin: 0 2%;
}
+div.patient a {
+ text-decoration: none; color: #000;
+}
+
+div.therapies > a {
+ display: inline-block;
+ text-decoration: none;
+ border: 1px solid black;
+ margin-top: .5em; padding: .25em .5em;
+ background-color: #DDF;
+ color: #000;
+}
+div.therapies > a.current {
+ background-color: #AAF;
+}
+
+div.prescription {
+ background-color: #CFF;
+}
+div.prescription h3 {
+ margin-top: .5em;
+}
+
div.prescription span {
display: inline-block;
width: 50%;
padding: .5ex 1ex;
}
-div.prescription ul {margin-top: 0;}
+div.prescription ul {
+ margin-top: .5em;
+ margin-left: 1.5em;
+}
div.prescription label.checkbox,
div.prescription label.radio {
}
input.stickynote + .stickynote > * { display: none; }
+input.stickynote + .stickynote > textarea {
+ display: block;
+ position: absolute;
+ left; 0; right: 0; bottom: 0; top: 0;
+ width: 100%; height: 100%;
+ background-color: #FF8;
+ padding: 2em 1em;
+}
input.stickynote + .stickynote > label {
position: absolute;
- top: 0; bottom: 0; right: .5ex;
+ top: 0; bottom: 0; right: .5ex; left: 0;
display: block;
text-align: right;
font-weight: bold;
+ z-index: 1;
}
input.stickynote + .stickynote:hover {
- left: -1ex;
+ width: auto; left: 0em; right: 2em;
}
input.stickynote:checked + .stickynote {
width: auto; left: 1em; right: 1em;
}
input.stickynote:checked + .stickynote > * { display: block; }
-input.stickynote:checked + .stickynote > textarea {
- display: block;
- position: absolute;
- left; 0; right: 0; bottom: 0; top: 0;
- width: 100%; height: 100%;
- background-color: #FF8;
- padding: 2em 1em;
-}
input.stickynote:checked + .stickynote > button[type="submit"] {
display: block;
position: absolute;
input.stickynote:checked + .stickynote > label:before {
position: absolute;
font-size: initial;
+ line-height: 1em;
content: "x";
top: .5ex; right: .5ex;
padding: .125ex .75ex;
@media(min-width: 800px){
h1, label.tab, div.tab, fieldset.tab,
- div.patient, div.prescription {
+ div.patient, div.prescription, div.therapies {
width: 38%;
margin-right: 0;
}
+ input.stickynote + .stickynote:hover { right: calc(50% + 1em); }
input.stickynote:checked + .stickynote { right: 50%; }
fieldset.penwidth,
fieldset.color { position: fixed; }
h1 {display: none;}
-div.patient, div.prescription { margin-top: 1em; }
-div.prescription {
+div.patient, div.prescription, div.therapies { margin-top: .5em; }
+div.prescription, div.therapies {
border: 1px solid black;
- background-color: #EEE;
padding: .125em 1.25ex .5em 1.25ex;
}
div > h2 { margin: 0; border-bottom: 1px solid black; }
+/*
div:nth-child(n+2) > a:first-of-type {
display: block;
margin: .125em 0 .5em 0;
text-decoration: none;
}
+*/
#report fieldset.tab,
#report label.tab {
-// Copyright 2016 Paul Hänsch
+// Copyright 2016, 2020 Paul Hänsch
//
// This file is part of Confetti.
//
body = document.body
dbg = document.getElementById("jsdebug")
canvas = document.getElementById("canvas")
-data=document.getElementById("image_serialize")
+data = document.getElementById("image_serialize")
image = canvas.getContext("2d")
mouse = 0
image_serialize=""
+image.lineJoin = "round"
+image.lineCap = "round"
+data.value += " stroke-linejoin round "
+data.value += " stroke-linecap round "
// start and current coordinates of a draw
// serves for tracking, whether path ends close to its beginning
setstroke(document.querySelector('input[name="penwidth"]:checked').value);
setcol(document.querySelector('input[name="color"]:checked').value);
- image.beginPath()
- draw(x, y) // why must this not use relative Coords ???
+ image.beginPath();
+ draw(x, y); // why must this not use relative Coords ???
- image_serialize = " polyline"
+ image_serialize = " polyline " + stx + "," + sty;
}
function drawstop() {
// if path ends close to beginning ( < 50 px); then close path and fill
- if ( false && mouse == 1 && Math.sqrt( Math.pow(stx - cux, 2) + Math.pow(sty - cuy, 2)) <= 50 && c !== "#FFF" ){
+ if ( mouse == 1 && Math.sqrt( Math.pow(stx - cux, 2) + Math.pow(sty - cuy, 2)) <= 50 && c !== "#FFF" ){
image.lineTo( stx, sty )
image.stroke()
--- /dev/null
+#!/bin/zsh
+
+# Copyright 2016, 2020 Paul Hänsch
+#
+# This file is part of Confetti.
+#
+# Confetti is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Confetti is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Confetti. If not, see <http://www.gnu.org/licenses/>.
+
+. "$_EXEC/pdiread.sh"
+tpy="$(POST id)"
+
+tpyfile="$_DATA/therapies/${tpy}.tpy"
+tempfile="$_DATA/temp/${tpy}.$$.tpy"
+
+if [ "$(POST tid)" != "$(transid "$tpyfile")" ]; then
+ if [ "$(POST autosubmit)" = "true" ]; then
+ printf 'Status: 409 Conflict\r\nContent-Length: 0\r\n\r\n'
+ exit 0
+ else
+ SET_COOKIE session message="TRANSACTION_CONFLICT"
+ REDIRECT "/therapies/${tpy%.*}/${tpy#*.}"
+ fi
+fi
+
+if [ "$(POST formend)" != "formend" ]; then
+ if [ "$(POST autosubmit)" = "true" ]; then
+ printf 'Status: 409 Conflict\r\nContent-Length: 0\r\n\r\n'
+ exit 0
+ else
+ SET_COOKIE session message="INCOMPLETE_SUBMIT"
+ REDIRECT "/therapies/${tpy%.*}/${tpy#*.}"
+ fi
+fi
+
+# serialize POST array into file
+for key in $(POST_KEYS); do
+ case "$key" in
+ imagedata|tid|formend) : ;;
+ session*_date)
+ value="$(POST "$key")"
+ y=0 mon=0 dom=0
+ case $value in
+ *.*.*) IFS=. read dom mon y <<-END
+ ${value}
+ END
+ ;;
+ *.*.) IFS=. read dom mon <<-END
+ ${value}
+ END
+ ;;
+ */*/*) IFS=/ read mon dom y <<-END
+ ${value}
+ END
+ ;;
+ */*) IFS=/ read mon dom <<-END
+ ${value}
+ END
+ ;;
+ *-*-*) IFS=- read y mon dom <<-END
+ ${value}
+ END
+ ;;
+ esac
+ [ ! "$y" ] && y="$(date +%Y)"
+ [ "$y" -gt 0 -a "$y" -lt 100 ] && y="$((y + 2000))"
+ date -d "${y}-${mon}-${dom}" + && printf %s:%s\\n "$key" "$(date -d "${y}-${mon}-${dom}" +%F)" \
+ || printf %s:\\n "$key"
+ ;;
+ *) printf %s:%s\\n "$key" "$(pdi_escape "$(POST "$key")")" ;;
+ esac
+done >"$tempfile" 2>&-
+
+if [ "$(POST delete_session)" ]; then
+ n="$(POST delete_session)"
+ sed -Ei '/^session'$n'[_:]/d' "$tempfile"
+ rm "${tpyfile%.tpy}_session${n}.png"
+
+ while grep -Eq '^session'$(($n + 1))'_' "$tempfile"; do
+ sed -Ei 's;^session'$(($n + 1))'(_|:);session'$n'\1;' "$tempfile"
+ mv "${tpyfile%.tpy}_session$(($n+1)).png" "${tpyfile%.tpy}_session${n}.png"
+ n=$(($n+1))
+ done
+
+elif [ "$(POST new_session)" ]; then
+ sid="$(POST new_session)"
+
+ read junkx junky dim junkz <<-E_READ
+ $(identify "$_EXEC/therapies/therapy_background.png")
+ E_READ
+
+ convert -size "$dim" xc:transparent "${tpyfile%.tpy}_${sid}.png"
+
+ printf '%s:exists\n' "$sid" >>"$tempfile"
+ printf '%s_open:checked\n' "$sid" >>"$tempfile"
+
+elif [ "$(POST imagedata)" ]; then
+ sid="$(sed -En 's;^(session[0-9]+)_open:checked$;\1;p' "$tempfile" \
+ | sort -n \
+ | tail -n1
+ )"
+
+ convert "${tpyfile%.tpy}_${sid}.png" \
+ -draw "$(POST imagedata)" -transparent white \
+ "${tpyfile%.tpy}_${sid}.png"
+ sync
+fi
+
+if ! diff -q "$tempfile" "$tpyfile" >/dev/null; then
+ mv "$tempfile" "$tpyfile"
+ rm -f -- "${_DATA}/cache/${tpy%%.*}.vcf.cache"
+fi
+
+if [ "$(POST autosubmit)" = "true" ]; then
+ msg="$(transid "$tpyfile")"
+ printf 'HTTP/1.1 200 OK\r\nContent-Length: %i\r\n\r\n%s' \
+ "${#msg}" "${msg}"
+elif [ "$(POST vcfreturn)" ]; then
+ REDIRECT "/cards/#${tpy%.*}.vcf"
+else
+ REDIRECT "/therapies/${tpy%.*}/${tpy#*.}"
+fi
+++ /dev/null
-# Copyright 2016 Paul Hänsch
-#
-# This file is part of Confetti.
-#
-# Confetti is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Confetti is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Confetti. If not, see <http://www.gnu.org/licenses/>.
-
-. $_EXEC/templates/text_prescriptions.sh
-
-item_name[prescriptionlist]="Zur Verordnungsliste"
-item_name[delete_session]="Therapiesitzung entfernen"
-item_name[therapist]="Therapeut"
-item_name[number]="Nr."
-item_name[signature]="Un­ter­schrift"
-item_name[weekly]="p. Woche"
-item_name[notes]="Notizen"
-item_name[trailsave]="Speichern für weitere Felder"
+++ /dev/null
-# Copyright 2016, 2017 Paul Hänsch
-#
-# This file is part of Confetti.
-#
-# Confetti is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Confetti is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Confetti. If not, see <http://www.gnu.org/licenses/>.
-
-t_session_note(){
- session_n="$1"
- note_n="$2"
-
- color=session${session_n}_note${note_n}_color
- unset c0 c1 c2 c3 c4 c5 c6 c7
-
- if [ "$note_n" -eq 1 -o -n "${tpy[session${session_n}_note${note_n}]}" ]; then
- printf '<input class="trailbtn" type="checkbox" checked="checked">'
- else
- printf '<input class="trailbtn" type="checkbox">'
- fi
-
- _checked="$(validate "$tpy[$color]" '#(888|00A|0A0|0AA|A00|A0A|AA0)' '#FFF')"
- cat <<-EOF
- <fieldset class="note trailbox">
- <input class=color type=radio name="$color" value="#888" id=${color}_000 $(checked \#888)><label for=${color}_000></label>
- <input class=color type=radio name="$color" value="#00A" id=${color}_001 $(checked \#00A)><label for=${color}_001></label>
- <input class=color type=radio name="$color" value="#0A0" id=${color}_010 $(checked \#0A0)><label for=${color}_010></label>
- <input class=color type=radio name="$color" value="#0AA" id=${color}_011 $(checked \#0AA)><label for=${color}_011></label>
- <input class=color type=radio name="$color" value="#A00" id=${color}_100 $(checked \#A00)><label for=${color}_100></label>
- <input class=color type=radio name="$color" value="#A0A" id=${color}_101 $(checked \#A0A)><label for=${color}_101></label>
- <input class=color type=radio name="$color" value="#AA0" id=${color}_110 $(checked \#AA0)><label for=${color}_110></label>
- <input class=color type=radio name="$color" value="#FFF" id=${color}_111 $(checked \#FFF)><label for=${color}_111></label>
- <textarea name="session${session_n}_note${note_n}">${tpy[session${session_n}_note${note_n}]}</textarea>
- </fieldset>
- EOF
-}
-
-t_session(){
- session_n="$1"
-
- sid=session${session_n}
-
- if [ "$tpy[${sid}_sigset]" = pos ]; then
- sigcheck=checked
- else
- unset sigcheck
- fi
-
- cat <<-EOF
- <input type=hidden name=$sid value=exists>
- <input class="tab" type="checkbox" id=${sid}_open name="${sid}_open" value="checked" ${tpy[${sid}_open]}>
- <label class="tab" for="${sid}_open">
- <span class=no>${session_n}.</span><!--
- --><span class=date>${tpy[${sid}_date]}</span><!--
- --><input class="date" name="${sid}_date" value="${tpy[${sid}_date]}" placeholder="$(l10n date)"><!--
- --><span class=therapist>${tpy[${sid}_therapist]}</span><!--
- --><input class="therapist" name="${sid}_therapist" value="${tpy[${sid}_therapist]}" placeholder="$(l10n therapist)"><!--
- --><span class=signature><input type="checkbox" name="${sid}_sigset" value="pos" $sigcheck></span>
- </label>
- <div class=tab>
- <img class="dotmark ov" src="/therapies/${id%.tpy}_${sid}.png" alt="">
- $(n=1;
- while [ -n "${tpy[session${session_n}_note${n}]+x}" ]; do
- if [ -n "${tpy[session${session_n}_note${n}]}" ]; then
- x=$n
- fi
- n=$(($n + 1))
- done
- for n in $(seq 1 $((${x:-0} + 3)) ); do t_session_note $session_n $n; done
- )
- <button class="trailbtn" type="submit">$(l10n trailsave)</button>
- <button class=delete type=submit name=delete_session value=${session_n}>$(l10n delete_session)</button>
- </div>
- EOF
-}
-
-therapy_sessions(){
- n=1; while [ -n "${tpy[session${n}]}" ]; do
- t_session $n
- n=$(($n+1))
- done
-
- sid=session$n
-
- cat <<-EOF
- <fieldset class="tab">
- <button class=no type=submit name=new_session value=$sid>+</button><!--
- --><input class=date name=${sid}_date value="" placeholder="$(l10n date)" /><!--
- --><input class=therapist name=${sid}_therapist value="" placeholder="$(l10n therapist)" /><!--
- --><span class=signature><span></span>
- <input type=hidden name="${sid}_note1" value="">
- </fieldset>
- EOF
-}
-
-cat <<EOF
-<h1>$(l10n therapy)</h1>
-
-<div class="patient">
- <h2>$client_name</h2>
- <a href="?p=prescriptions&client=${id%%.*}.vcf">< $(l10n prescriptionlist)</a>
-</div>
-
-<div class="prescription">
- <h2>$(l10n therapy_prescription)</h2>
- <span class="insurance">${mpx[insurance]}</span>
- <span class="date"><label>$(l10n date):</label>${mpx[date]}</span>
-
- <label class="checkbox ${mpx[prescreviewed]:+checked}" for="prescreviewed">
- $([ -n "${mpx[prescreviewed]}" ] && printf %s "$(l10n prescreviewed)" \
- || printf %s "$(l10n prescreview)" )
- </label>
-
- ${mpx[prescno]:+<span class="prescno">$(l10n presc${mpx[prescno]})</span>}
- ${mpx[grouptherapy]:+<span class="catalogue">$(l10n grouptherapy)</span>}
- ${mpx[housecall]:+<span class="catalogue">$(l10n housecall)</span>}
- ${mpx[report]:+<span class="catalogue">$(l10n report)</span>}
-
- <ul>$(for n in '' {0..10}; do
- [ -n "${mpx[remidy$n]}" ] && \
- printf '<li>%s %s %s</li>' "${mpx[quantity$n]}" \
- "${mpx[remidy$n]}" \
- "${mpx[quantity_weekly$n]:+($mpx[quantity_weekly$n] $(l10n weekly))}"
- done)</ul>
-
- ${mpx[indicator]:+<span class="indicator"><label>$(l10n indicator):</label>${mpx[indicator]}</span>}
- ${mpx[icd10]:+<span class="icd10"> <label>$(l10n icd10):</label>${mpx[icd10]}</span>}
-
- ${mpx[addcontrib]:+
- <label class='checkbox ${mpx[contribconfirm]:+checked}' for="addcontrib">
- $([ -n "${mpx[contribconfirm]}" ] && printf %s "$(l10n contribconfirm)" ${mpx[contribconfirm]} \
- || printf %s "$(l10n addcontrib)" )
- </label>
- }
-
- <input class="tab" type="checkbox" id="indicator_reading">
- <label class="tab" for="indicator_reading">$(l10n indicator_reading)</label>
- <div class="tab">${mpx[indicator_reading]}</div>
-</div>
-
-<form id="report" method="POST" action="?action=update_therapy">
- <input type="hidden" name="id" value="${id}">
-
- <input class="stickynote" type="checkbox" name="c_stickynote" id="show_stickynote">
- <fieldset class="stickynote">
- <label for="show_stickynote">$(l10n notes)</label>
- <h2>$(l10n notes)</h2>
- <textarea name="stickynote">${tpy[stickynote]}</textarea>
- <button type="submit">$(l10n save)</button>
- </fieldset>
-
- <input class="stickynote" type="checkbox" name="c_timesheet" id="show_timesheet">
- <fieldset class="stickynote">
- <label for="show_timesheet">$(l10n timesheet)</label>
- <h2>$(l10n timesheet)</h2>
- <table><thead>
- <tr><th>$(l10n time_goal)</th><th>$(l10n time_actual)</th><th>$(l10n time_difference)</th></tr>
- </thead><tbody>
- $(for n in '' {0..10}; do
- printf '<tr><td><input type="number" name="tsgoal" value="%s"/></td>
- <td><input type="number" name="tsactual" value="%s"/></td>
- <td>%s</td>
- </tr>\n' \
- "$mpx[tsgoal${n}]" "$mpx[tsactual${n}]" "$((${mpx[tsgoal${n}]:-0} - ${mpx[tsactual${n}]:-0}))"
- done)
- </tbody></table>
- <button type="submit">$(l10n save)</button>
- </fieldset>
-
- <!--input class="tab" type="checkbox" id="lookout">
- <label class="tab" for="lookout">$(l10n indicator_reading)</label>
- <div class="tab"><textarea name="lookout">${mpx[lookout]}</textarea -->
-
- <label class="tab heading">
- <span class=no>$(l10n number)</span><!--
- --><span class=date>$(l10n date)</span><!--
- --><span class=therapist>$(l10n therapist)</span><!--
- --><span class=signature>$(l10n signature)</span>
- </label>
-EOF
-
-therapy_sessions
-
-_checked="$(validate "$tpy[penwidth]" '(4|12|36)' '4')"
-cat <<EOF
- <fieldset class="penwidth">
- <input type="radio" name="penwidth" value="4" id="pw1" $(checked 4)><label for="pw2"></label>
- <input type="radio" name="penwidth" value="12" id="pw2" $(checked 12)><label for="pw3"></label>
- <input type="radio" name="penwidth" value="36" id="pw3" $(checked 36)><label for="pw1"></label>
- </fieldset>
-EOF
-
-_checked="$(validate "$tpy[color]" '#(0[0A]{2}|A00|A0A|AA0|FFF)' '#000')"
-cat <<EOF
- <fieldset class="color">
- <input class="color" type="radio" name="color" value="#000" id="c000" $(checked \#000)><label for="c000"></label>
- <input class="color" type="radio" name="color" value="#00A" id="c001" $(checked \#00A)><label for="c001"></label>
- <input class="color" type="radio" name="color" value="#0A0" id="c010" $(checked \#0A0)><label for="c010"></label>
- <input class="color" type="radio" name="color" value="#0AA" id="c011" $(checked \#0AA)><label for="c011"></label>
- <input class="color" type="radio" name="color" value="#A00" id="c100" $(checked \#A00)><label for="c100"></label>
- <input class="color" type="radio" name="color" value="#A0A" id="c101" $(checked \#A0A)><label for="c101"></label>
- <input class="color" type="radio" name="color" value="#AA0" id="c110" $(checked \#AA0)><label for="c110"></label>
- <input class="color" type="radio" name="color" value="#FFF" id="c111" $(checked \#FFF)><label for="c111"></label>
- </fieldset>
- <img class="dotmark bg" src="?static=therapy_background.png" alt="WARNING: Background Image not available!">
- <canvas id="canvas" class="dotmark ov" width="${bg_dim%x*}" height="${bg_dim#*x}"></canvas>
-
- <input type=hidden id=image_serialize name=imagedata value="">
-
- <button type="submit">$(l10n save)</button>
-</form>
-
-<span id="jsdebug" style="display: none; position: fixed; right:0; bottom:0">Debug</span>
-
-<script type="text/javascript" src="?static=therapy_draw.js"></script>
-EOF
-
-# vi:set filetype=html:
+++ /dev/null
-#!/bin/zsh
-
-# Copyright 2016 Paul Hänsch
-#
-# This file is part of Confetti.
-#
-# Confetti is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Confetti is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Confetti. If not, see <http://www.gnu.org/licenses/>.
-
-declare -A tpy
-declare -A mpx
-
-BR='
-'
-
-id="$_GET[id]"
-
-tpyfile="$_DATA/therapies/$id"
-mpxfile="$_DATA/prescriptions/${id%.tpy}.mpx"
-client="$_DATA/vcard/${id%%.*}.vcf"
-
-identify "$_EXEC/static/therapy_background.png" \
-| sed -r 's;^.* ([0-9]+x[0-9]+) .*$;\1;' \
-| read bg_dim
-
-card_N="$(sed -nr 's:^(N)(;[^"\:]+|;"[^"]+")*\:(.*)$:\3:gp' "$client")"
-card_FN="$(sed -nr 's:^(FN)(;[^"\:]+|;"[^"]+")*\:(.*)$:\3:gp' "$client")"
-card_NICK="$(sed -nr 's:^(NICKNAME)(;[^"\:]+|;"[^"]+")*\:(.*)$:\3:gp' "$client")"
-
-n=$(printf %s "$card_N" \
- | sed -rn 's:^([^;]*)(\;[^;]*)(\;[^;]*)?(\;[^;]*)?(\;[^;]*)?$:\4 \2 \3 \1 \5:gp' \
- | sed -r 's:,: :;s:\;: :g;s: +: :g;s:^ $::;'
- )
-client_name="${n:-${card_FN:-${card_NICK}}}"
-
-mpx=()
-cat "$mpxfile" |while read -r line; do
- val="${line#*:}"
- mpx[${line%%:*}]="$(htmlsafe "${val//\\n/$BR}")"
-done
-
-tpy=()
-cat "$tpyfile" |while read -r line; do
- val="${line#*:}"
- tpy[${line%%:*}]="$(htmlsafe "${val//\\n/$BR}")"
-done
+++ /dev/null
-#!/bin/zsh
-
-# Copyright 2016 Paul Hänsch
-#
-# This file is part of Confetti.
-#
-# Confetti is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Confetti is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Confetti. If not, see <http://www.gnu.org/licenses/>.
-
-BR='
-'
-tpy="${_POST[id]}"
-
-tpyfile="$_DATA/therapies/$tpy"
-tempfile="$_DATA/temp/$tpy"
-
-# serialize POST array into file
-for key in ${(k)_POST}; do
- [ "$key" != imagedata ] && printf %s:%s\\n "$key" "${_POST[$key]//$BR/\\n}"
-done >"$tempfile"
-
-if [ -n "$_POST[delete_session]" ]; then
- n="$_POST[delete_session]"
- sed -i -r '/^session'$n'[_:]/d' "$tempfile"
- rm "${tpyfile%.tpy}_session${n}.png"
-
- while grep -Eq '^session'$(($n + 1))'_' "$tempfile"; do
- sed -i -r 's;^session'$(($n + 1))'(_|:);session'$n'\1;' "$tempfile"
- mv "${tpyfile%.tpy}_session$(($n+1)).png" "${tpyfile%.tpy}_session${n}.png"
- n=$(($n+1))
- done
-
-elif [ -n "$_POST[new_session]" ]; then
- sid="$_POST[new_session]"
-
- identify "$_EXEC/static/therapy_background.png" \
- | sed -r 's;^.* ([0-9]+x[0-9]+) .*$;\1;' \
- | read dim
-
- convert -size "$dim" xc:transparent "${tpyfile%.tpy}_${sid}.png"
-
- printf '%s:exists\n' "$sid" >>"$tempfile"
- printf '%s_open:checked\n' "$sid" >>"$tempfile"
-
-elif [ -n "$_POST[imagedata]" ]; then
- sed -rn 's;^(session[0-9]+)_open:checked$;\1;p' "$tempfile" \
- | sort -n \
- | tail -n1 \
- | read sid
-
- convert "${tpyfile%.tpy}_${sid}.png" \
- -strokewidth 2 -fill '#00000000' \
- -draw "${_POST[imagedata]}" -transparent white \
- "${tpyfile%.tpy}_${sid}.png"
- sync
-fi
-
-mv "$tempfile" "$tpyfile"
-
-redirect "?p=therapy&id=${tpy}"