pdf export of course lists
authorPaul Hänsch <paul@plutz.net>
Wed, 20 Jan 2021 23:37:58 +0000 (00:37 +0100)
committerPaul Hänsch <paul@plutz.net>
Wed, 20 Jan 2021 23:37:58 +0000 (00:37 +0100)
courses/course_print.sh [deleted file]
courses/export_pdf.sh [new file with mode: 0755]
courses/generate_courselist.sh [deleted file]
index.cgi

diff --git a/courses/course_print.sh b/courses/course_print.sh
deleted file mode 100755 (executable)
index 72ab8b8..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2014 - 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_cards.sh
-
-echo -E '
-\documentclass[landscape,10pt]{article}
-\usepackage[utf8x]{inputenc}
-\usepackage{ngerman}
-\usepackage{eurosym}
-\usepackage[landscape,margin=0.25in]{geometry}
-\usepackage{longtable}
-
-\begin{document}
-
-\section*{Teilnehmende}
-\begin{longtable}{|p{60mm}|l|p{50mm}|p{80mm}|}
-\hline
-  \textbf{'"$(l10n N)"'} &
-  \textbf{'"$(l10n BDAY)"'} &
-  \textbf{'"$(l10n TEL)"'} &
-  \textbf{'"$(l10n NOTE)"'} \\
-\hline
-\hline
-\endhead
-'"$(
-list_attendance "$course" |sort -k 2 |while read line; do
-  cardfile="$(echo "$line" |cut -d\  -f1)"
-  list_attendee "$cardfile" |sed -r 's:$:\\\\[3ex] \\hline:'
-done
-)"'
-\end{longtable}
-
-\newpage
-
-\section*{Termine}
-\begin{longtable}{|p{60mm}|c|c|c|c|c|c|c|c|c|c|}
-\hline
- '"$(get_dates)"' \\
-\hline
-\hline
-\endhead
-'"$(
-tex_clean "$(list_attendance "$course")" |sort -k 2 | debug |sed -r 's:^[0-9a-z\.]+ (.+) \(\*[0-9]{4}\)$:\1:;s:$: \& \& \& \& \& \& \& \& \& \& \\\\[3ex] \\hline:'
-)"'
-\end{longtable}
-
-\end{document}
-'
diff --git a/courses/export_pdf.sh b/courses/export_pdf.sh
new file mode 100755 (executable)
index 0000000..7a9a9dd
--- /dev/null
@@ -0,0 +1,123 @@
+#!/bin/sh
+
+. "${_EXEC}/pdiread.sh"
+. "$_EXEC/cards/l10n.sh"
+
+coursefile="${_DATA}/ical/$(GET course)"
+
+if [ ! -r "$coursefile" ]; then
+  SET_COOKIE 0 message="Cannot read course file"
+  REDIRECT /courses/
+  return 0
+elif ! mkdir -p "$_DATA/export"; then
+  SET_COOKIE 0 message="Cannot create export directory"
+  REDIRECT /courses/
+  return 0
+fi
+
+ics="$(pdi_load "$coursefile")"
+htmlfile="${_DATA}/export/$(pdi_value "$ics" SUMMARY |URL |tr / _).html"
+pdffile=${htmlfile%.html}.pdf
+
+pdi_date() {
+  local pdt y m d H M S Z
+  [ $# -eq 0 ] && read pdt || pdt="$*"
+
+  case $pdt in
+    *T*Z)
+      Z=UTC; pdt="${pdt%Z}";;
+    TZID=*:*T*)
+      Z="${pdt%%:*}"; Z=${Z#TZID=}; pdt=${pdt#TZID=*:};;
+  esac
+
+  y="${pdt%%????T*}" pdt=${pdt#????}
+  m="${pdt%%??T*}" pdt=${pdt#??}
+  d="${pdt%%T*}" pdt=${pdt#??T}
+  H="${pdt%%????}" pdt=${pdt#??}
+  M="${pdt%%??}" pdt=${pdt#??}
+  S="${pdt}" pdt=''
+
+  case Z in 
+    UTC) date -d "${y}-${m}-${d} ${H}:${M}:${S} UTC" +%s;;
+     '') date -d "${y}-${m}-${d} ${H}:${M}:${S}" +%s;;
+      *) date -d "TZ=\"${Z}\" ${y}-${m}-${d} ${H}:${M}:${S}" +%s;;
+  esac
+}
+
+get_dates() {
+  local dts_date rrule rr_int rr_freq rec today="$(date +%Y%m%d)"
+
+  dts_date="$(pdi_value "$ics" DTSTART || printf %s "$today")"
+  dts_date="${dts_date#TZID=*:}" dts_date="${dts_date%%T*}"
+  rrule="$(pdi_value "$ics" RRULE)"
+  rr_int="${rrule##*INTERVAL=}" rr_int="${rr_int%%;*}"
+  rr_freq="${rrule##*FREQ=}" rr_freq="${rr_freq%%;*}"
+
+  [ "$rr_int" -ge 0 ] || rr_int=1 2>/dev/null
+  case "$rr_freq" in
+    YEARLY)  rec="$rr_int year";;
+    MONTHLY) rec="$rr_int month";;
+    DAILY)   rec="$rr_int day";;
+    WEEKLY)  rec="$rr_int week";;
+    *) rec="$rr_int week";;
+  esac
+
+  while [ "$dts_date" -lt "$today" ]; do dts_date="$(date -d "${dts_date} + ${rec}" +%Y%m%d)"; done
+  for n in 1 2 3 4 5 6 7 8 9 10; do
+    LANG=de_DE.UTF-8 date -d "$dts_date" +"%A, %d. %b."
+    dts_date="$(date -d "${dts_date} + ${rec}" +%Y%m%d)"
+  done
+}
+
+"$_EXEC/cgilite/html-sh.sed" <<-EOF |sed -E 's;<(td|th)([^>]*)>;<\1 \2 style="border: 1pt solid\; padding: 1mm 2mm\;">;g' >"$htmlfile"
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+[html [head
+  [meta http-equiv="content-type" content="text/html; charset=utf-8"]
+  [title]
+  [meta name="generator" content="Confetti"]
+  [meta name="created" content="$(date +%FT%T)"]
+  [meta name="changed" content="$(date +%FT%T)"]
+  [style type="text/css"
+    @page { size: 29.7cm 21cm; margin: 1.5cm; }
+    * { background: inherit; }
+    body { background: transparent; font-family: Liberation Sans, Sans-Serif; }
+
+    th { white-space: pre; }
+    th, td { text-align: left; }
+  ]
+][body lang="de_DE"
+  [table width="100%"
+    [col width=10*] [col width=5*] [col width=10*] [col width=15*]
+    [thead
+      [tr [th . $(l10n N)] [th . $(l10n BDAY)] [th . $(l10n TEL)] [th . $(l10n NOTE)]]
+    ][tbody
+      $(grep -F "${coursefile##*/}     " "$_DATA/mappings/attendance" |while read discard each; do
+        vcf="$(pdi_load "$_DATA/vcard/$each")"
+        tel="$( seq 1 $(pdi_count "$vcf" TEL) |while read n; do
+                  type="$(pdi_attrib "$vcf" TEL $n TYPE)"
+                  [ "$type" ] && type="$(l10n "TYPE=$type"):"
+                  printf '%s %s<br>' "$type" "$(pdi_value "$vcf" TEL $n)"
+                done  )"
+        printf '[tr [td .N . %s] [td .BDAY . %s] [td .TEL . %s] [td .NOTE . %s]]\n' \
+               "$(pdi_value "$vcf" FN   |unescape |HTML)" \
+               "$(pdi_value "$vcf" BDAY |unescape |HTML)" \
+               "$tel" \
+               "$(pdi_value "$vcf" NOTE |unescape |HTML)"
+      done |sort -k4)]
+  ]
+  [table width="100%" style="page-break-before: always;"
+    [col width=30*] [col width=10*] [col width=10*] [col width=10*] [col width=10*] [col width=10*] [col width=10*] [col width=10*] [col width=10*] [col width=10*] [col width=10*]
+    [thead
+      [tr [th ] $(get_dates |xargs -d\\n printf '[th . %s]')]
+    ][tbody
+    $(grep -F "${coursefile##*/}       " "$_DATA/mappings/attendance" |while read discard each; do
+      vcf="$(pdi_load "$_DATA/vcard/$each")"
+      printf '[tr [td .N . %s] [td] [td] [td] [td] [td] [td] [td] [td] [td] [td]]\n' \
+             "$(pdi_value "$vcf" FN |unescape |HTML)"
+    done |sort -k4)]
+  ]
+]]
+EOF
+
+lowriter --convert-to pdf --outdir "$_DATA/export/" "$htmlfile"
+REDIRECT "/export/${pdffile##*/}"
diff --git a/courses/generate_courselist.sh b/courses/generate_courselist.sh
deleted file mode 100755 (executable)
index d777536..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-#!/bin/zsh
-
-# Copyright 2014, 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/>. 
-
-pdflatex="$(where pdflatex |head -n1 || echo false)"
-course="${_GET[course]}"
-fromdate="${_GET[fromdate]}"
-fromdate="$(date -d "$fromdate" +%s)" 2>/dev/null
-[ -z "$fromdate" ] && fromdate=$(date +%s)
-
-. ${_EXEC}/pages/courses.sh
-. ${_EXEC}/pages/cards.sh
-
-tex_clean() { #in dire need for improvement
-  printf %s "$*" |tr -d '{&}\\"'
-}
-
-
-list_attendee() {  #Parameter: Cardfile
-  id="$1"
-  cardfile="$_DATA/vcard/${id}"
-
-  declare -A values
-
-  if [ -r "$cardfile" ]; then
-    vcf_parse "$cardfile"
-
-    n=$(printf %s "$values[N]" \
-        | sed -rn 's:^([^;]*)(;[^;]*)(;[^;]*)?(;[^;]*)?(;[^;]*)?$:\4 \2 \3 \1 \5:gp' \
-        | sed -r 's:,: :;s:;: :g;s: +: :g;s:^ $::;'
-       )
-    fullname="${n:-${values[FN]:-${values[NICKNAME]}}}"
-
-    tel=''
-    for n in TEL TEL{0..10}; do if (echo "$values[$n]" |grep -Eq '[0-9]'); then
-      [ -n "$tel" ] && tel="$tel\\newline $(tex_clean "$values[$n]")" || tel="$(tex_clean "$values[$n]")"
-    fi; done
-
-    note=''
-    for n in NOTE NOTE{0..10}; do if [ -n "$values[$n]" ]; then
-      [ -n "$note" ] && note="$note\\newline $(tex_clean "$values[$n]")" || note="$(tex_clean "$values[$n]")"
-    fi; done
-    printf '%s & %s & %s & %s\n' \
-           "$(tex_clean $fullname)" "$(tex_clean $values[BDAY])" "$tel" "$note" \
-    | sed -r ':X;N;$!bX; s;\n;\\newline ;g'
-  fi
-}
-
-get_dates() {  #Parameter: Calendarfile
-  calendarfile="$_DATA/ical/$course"
-
-  declare -A values
-  ics_parse "$calendarfile"
-
-  dtstart="$values[DTSTART]"
-  [ -z "$dtstart" ] && dtstart=$(date +%Y%m%dT%H%M%S)
-  echo "$dtstart" |case "$dtstart" in
-    *Z)    sed -rn 's:^([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})Z$:\1-\2-\3 \4\:\5\:\6 UTC:p';;
-    TZID*) sed -rn 's:^TZID=(.+)\:([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})$:TZ="\1" \2-\3-\4 \5\:\6\:\7:p';;
-    *)     sed -rn 's:^([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})$:\1-\2-\3 \4\:\5\:\6:p';;
-  esac |read dts_date
-  rrule="$values[RRULE]"
-  rr_int="$(echo $rrule |sed -rn 's:^.*INTERVAL=([0-9]+)(;.*)?$:\1:p')"
-  rr_freq="$(echo $rrule |sed -rn 's:^.*FREQ=(YEARLY|MONTHLY|WEEKLY|DAILY)(;.*)?$:\1:p')"
-  case "$rr_freq" in
-    YEARLY) rec="$rr_int year";;
-    MONTHLY) rec="$rr_int month";;
-    DAILY) rec="$rr_int day";;
-    *) rec="$rr_int week";;
-  esac
-
-  next_date="$dts_date"
-  n=10
-  while [ $n -gt 0 ]; do
-    if [ "$(date -d "$next_date" +%s)" -gt "$(date +%s)" ]; then
-      dtlist="$dtlist & $(date -d "$next_date" +"%d. %b.")"
-      n=$(($n - 1))
-    fi
-    next_date="$(date -d "$next_date + $rec" +%Y-%m-%d)"
-  done
-
-  echo "$dtlist"
-}
-
-if [ -r "${_DATA}/ical/${course}" ]; then
-  . ${_EXEC}/templates/course_print.sh >"${_DATA}/temp/courselist_${course}.tex"
-  [ -e "${_DATA}/temp/courselist_${course}.pdf" ] && rm "${_DATA}/temp/courselist_${course}.pdf"
-  "$pdflatex" -halt-on-error -output-directory "${_DATA}/temp/" "${_DATA}/temp/courselist_${course}.tex" |debug >/dev/null
-  "$pdflatex" -halt-on-error -output-directory "${_DATA}/temp/" "${_DATA}/temp/courselist_${course}.tex" |debug >/dev/null
-fi
-if [ -r "${_DATA}/temp/courselist_${course}.pdf" ]; then
-  echo 'Content-Type: application/x-pdf\n'
-  cat "${_DATA}/temp/courselist_${course}.pdf"
-fi
index 5dc55be..0cfa8a3 100755 (executable)
--- a/index.cgi
+++ b/index.cgi
@@ -65,17 +65,27 @@ yield_page() {
 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}"
+    ;;
+  *)
+    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