forked from digitales/kompass
tex: rewrite pdf generation, add seminar report, add some utility functions
parent
2eb664e35e
commit
ed8f3e9c0e
@ -0,0 +1,56 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
import unicodedata
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
import glob
|
||||||
|
from django.template.loader import get_template
|
||||||
|
from django.conf import settings
|
||||||
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
|
from wsgiref.util import FileWrapper
|
||||||
|
|
||||||
|
|
||||||
|
def media_path(fp):
|
||||||
|
return os.path.join(os.path.join(settings.MEDIA_MEMBERLISTS, "memberlists"), fp)
|
||||||
|
|
||||||
|
|
||||||
|
def media_dir():
|
||||||
|
return os.path.join(settings.MEDIA_MEMBERLISTS, "memberlists")
|
||||||
|
|
||||||
|
|
||||||
|
def render_tex(name, template_path, context):
|
||||||
|
filename = name + "_" + datetime.today().strftime("%d_%m_%Y")
|
||||||
|
filename = filename.replace(' ', '_').replace('&', '').replace('/', '_')
|
||||||
|
# drop umlauts, accents etc.
|
||||||
|
filename = unicodedata.normalize('NFKD', filename).encode('ASCII', 'ignore').decode()
|
||||||
|
filename_tex = filename + '.tex'
|
||||||
|
filename_pdf = filename + '.pdf'
|
||||||
|
|
||||||
|
tmpl = get_template(template_path)
|
||||||
|
res = tmpl.render(dict(context, creation_date=datetime.today().strftime('%d.%m.%Y')))
|
||||||
|
with open(media_path(filename_tex), 'w', encoding='utf-8') as f:
|
||||||
|
f.write(res)
|
||||||
|
|
||||||
|
# compile using pdflatex
|
||||||
|
oldwd = os.getcwd()
|
||||||
|
os.chdir(media_dir())
|
||||||
|
subprocess.call(['pdflatex', '-halt-on-error',filename_tex])
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# do some cleanup
|
||||||
|
for f in glob.glob('*.log'):
|
||||||
|
os.remove(f)
|
||||||
|
for f in glob.glob('*.aux'):
|
||||||
|
os.remove(f)
|
||||||
|
#os.remove(filename_tex)
|
||||||
|
#os.remove(filename_table)
|
||||||
|
|
||||||
|
os.chdir(oldwd)
|
||||||
|
|
||||||
|
# provide the user with the resulting pdf file
|
||||||
|
with open(media_path(filename_pdf), 'rb') as pdf:
|
||||||
|
response = HttpResponse(FileWrapper(pdf))#, content='application/pdf')
|
||||||
|
response['Content-Type'] = 'application/pdf'
|
||||||
|
response['Content-Disposition'] = 'attachment; filename='+filename_pdf
|
||||||
|
|
||||||
|
return response
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
{% load tex_extras %}
|
||||||
|
|
||||||
|
\documentclass{article}
|
||||||
|
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
\usepackage{booktabs}
|
||||||
|
\usepackage{amssymb}
|
||||||
|
\usepackage{cmbright}
|
||||||
|
\usepackage{graphicx}
|
||||||
|
\usepackage{textpos}
|
||||||
|
\usepackage[colorlinks, breaklinks]{hyperref}
|
||||||
|
\usepackage{float}
|
||||||
|
\usepackage[margin=1in]{geometry}
|
||||||
|
\usepackage{array}
|
||||||
|
\usepackage{tabularx}
|
||||||
|
|
||||||
|
\newcommand{\picpos}[4]{
|
||||||
|
\begin{textblock*}{#1}(#2, #3)
|
||||||
|
\includegraphics[width=\textwidth]{#4}
|
||||||
|
\end{textblock*}
|
||||||
|
}
|
||||||
|
|
||||||
|
% custom url command for properly formatting emails
|
||||||
|
\DeclareUrlCommand\Email{\urlstyle{same}}
|
||||||
|
% allow linebreak after every character
|
||||||
|
\expandafter\def\expandafter\UrlBreaks\expandafter{\UrlBreaks
|
||||||
|
\do\/\do\a\do\b\do\c\do\d\do\e\do\f\do\g\do\h\do\i\do\j\do\k
|
||||||
|
\do\l\do\m\do\n\do\o\do\p\do\q\do\r\do\s\do\t\do\u\do\v
|
||||||
|
\do\w\do\x\do\y\do\z
|
||||||
|
\do\A\do\B\do\C\do\D\do\E\do\F\do\G\do\H\do\I\do\J\do\K
|
||||||
|
\do\L\do\M\do\N\do\O\do\P\do\Q\do\R\do\S\do\T\do\U\do\V
|
||||||
|
\do\W\do\X\do\Y\do\Z}
|
||||||
|
|
||||||
|
\renewcommand{\arraystretch}{1.5}
|
||||||
|
|
||||||
|
\newcolumntype{L}{>{\hspace{0pt}}X}
|
||||||
|
\newcommand{\tickedbox}{
|
||||||
|
\makebox[0pt][l]{$\square$}\raisebox{.15ex}{\hspace{0.1em}$\checkmark$}
|
||||||
|
}
|
||||||
|
\newcommand{\checkbox}{
|
||||||
|
\makebox[0pt][l]{$\square$}
|
||||||
|
}
|
||||||
|
\begin{document}
|
||||||
|
% HEADER RIGHT
|
||||||
|
\picpos{4.5cm}{11.5cm}{0cm}{dav_logo.png}
|
||||||
|
\begin{textblock*}{5cm}(11.5cm, 2.3cm)
|
||||||
|
\begin{flushright}
|
||||||
|
\small
|
||||||
|
\noindent Deutscher Alpenverein e. V. \\
|
||||||
|
Sektion Ludwigsburg\\
|
||||||
|
Fuchshofstr. 66\\
|
||||||
|
71638 Ludwigsburg\\
|
||||||
|
Tel.: 07141 927893\\
|
||||||
|
Fax: 07141 924042\\
|
||||||
|
info@alpenverein-ludwigsburg.de\\
|
||||||
|
\end{flushright}
|
||||||
|
\end{textblock*}
|
||||||
|
|
||||||
|
% HEADLINE
|
||||||
|
{\noindent\LARGE{Teilnehmer:innenliste\\[2mm]Sektionsveranstaltung}}\\[1mm]
|
||||||
|
\textit{Erstellt: {{ creation_date }} }\\
|
||||||
|
|
||||||
|
% DESCRIPTION TABLE
|
||||||
|
\begin{table}[H]
|
||||||
|
\begin{tabular}{ll}
|
||||||
|
\large Aktivität: & {{ memberlist.name|esc_all }} \\
|
||||||
|
\large Gruppe: & {{ memberlist.groups_str|esc_all }} \\
|
||||||
|
\large Ziel: & {{ memberlist.place|esc_all }} \\
|
||||||
|
\large Stützpunkt: & {{ memberlist.destination|esc_all }} \\
|
||||||
|
\large Zeitraum: & {{ memberlist.time_period_str|esc_all }} \\
|
||||||
|
\large Betreuer:innen: & {{ memberlist.staff_str|esc_all }} \\
|
||||||
|
\large Art der Tour: & {% checked_if_true 'Gemeinschaftstour' memberlist.get_tour_type %}
|
||||||
|
{% checked_if_true 'Führungstour' memberlist.get_tour_type %}
|
||||||
|
{% checked_if_true 'Ausbildung' memberlist.get_tour_type %} \\
|
||||||
|
\large Anreise: & {% checked_if_true 'ÖPNV' memberlist.get_tour_approach %}
|
||||||
|
{% checked_if_true 'Muskelkraft' memberlist.get_tour_approach %}
|
||||||
|
{% checked_if_true 'Fahrgemeinschaften' memberlist.get_tour_approach %}
|
||||||
|
\end{tabular}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
\begin{table}[H]
|
||||||
|
\begin{tabularx}{1\linewidth}{@{\extracolsep{\fill}}lLlL}
|
||||||
|
\toprule
|
||||||
|
\textbf{Name} & \textbf{Anschrift} & \textbf{Telefon} & \textbf{E-Mail} \\
|
||||||
|
\midrule
|
||||||
|
{% for m in memberlist.membersonlist.all %}
|
||||||
|
{{ m.member.name|esc_all }} & {{ m.member.address|esc_all }} & {{ m.member.contact_phone_number|esc_all }} & \Email{ {{ m.member.contact_email }} } \\
|
||||||
|
{% endfor %}
|
||||||
|
\bottomrule
|
||||||
|
\end{tabularx}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
\vspace{1cm}
|
||||||
|
|
||||||
|
\noindent Bitte die ausgefüllte Teilnehmerliste vor Antritt der Aktivität per E-Mail an
|
||||||
|
\href{mailto:info@alpenverein-ludwigsburg.de}{info@alpenverein-ludwigsburg.de} und
|
||||||
|
\href{mailto:vorstand@alpenverein-ludwigsburg.de}{vorstand@alpenverein-ludwigsburg.de} senden.
|
||||||
|
|
||||||
|
\end{document}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
{% load tex_extras %}
|
||||||
|
|
||||||
|
\documentclass{article}
|
||||||
|
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
\usepackage{booktabs}
|
||||||
|
\usepackage{tabularx}
|
||||||
|
\usepackage{ragged2e}
|
||||||
|
\usepackage{amssymb}
|
||||||
|
\usepackage{cmbright}
|
||||||
|
\usepackage{graphicx}
|
||||||
|
\usepackage{textpos}
|
||||||
|
\usepackage[colorlinks]{hyperref}
|
||||||
|
\usepackage{float}
|
||||||
|
\usepackage[margin=1cm]{geometry}
|
||||||
|
|
||||||
|
\renewcommand{\arraystretch}{1.5}
|
||||||
|
|
||||||
|
\newcolumntype{Y}{>{\RaggedRight\arraybackslash}X}
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
% HEADLINE
|
||||||
|
{\noindent\LARGE{Teilnehmer:innenübersicht}}\\[1mm]
|
||||||
|
\textit{Erstellt: {{ creation_date }} }\\
|
||||||
|
|
||||||
|
% DESCRIPTION
|
||||||
|
\begin{table}[H]
|
||||||
|
\begin{tabular}{ll}
|
||||||
|
\large Aktivität: & {{ memberlist.name|esc_all }} \\
|
||||||
|
\large Gruppe: & {{ memberlist.groups_str|esc_all }} \\
|
||||||
|
\large Ziel: & {{ memberlist.place|esc_all }} \\
|
||||||
|
\large Stützpunkt: & {{ memberlist.destination|esc_all }} \\
|
||||||
|
\large Zeitraum: & {{ memberlist.time_period_str|esc_all }} \\
|
||||||
|
\end{tabular}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
\begin{table}[H]
|
||||||
|
\begin{tabularx}{\textwidth}{@{} l l Y @{}}
|
||||||
|
\toprule
|
||||||
|
\textbf{Name} & \textbf{Fähigkeiten (max. 100)} & \textbf{Kommentare} \\
|
||||||
|
\midrule
|
||||||
|
{% for p in people %}
|
||||||
|
{{ p.name|esc_all }} & {{ p.qualities|esc_all }} & {{ p.comments|esc_all }} \\
|
||||||
|
{% endfor %}
|
||||||
|
\bottomrule
|
||||||
|
\end{tabularx}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
\noindent\large Fähigkeiten der Gruppe\\
|
||||||
|
\begin{table}[H]
|
||||||
|
\begin{tabular*}{1\linewidth}{@{\extracolsep{\fill}}llll}
|
||||||
|
\toprule
|
||||||
|
\textbf{Name} & \textbf{Durchschnitt} & \textbf{Minimum} & \textbf{Maximum} \\
|
||||||
|
\midrule
|
||||||
|
{% for skill in skills %}
|
||||||
|
{{ skill.name|esc_all }} & {{ skill.skill_avg|esc_all }} & {{ skill.skill_min|esc_all }} & {{ skill.skill_max|esc_all }} \\
|
||||||
|
{% endfor %}
|
||||||
|
\bottomrule
|
||||||
|
\end{tabular*}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
\vspace{1cm}
|
||||||
|
|
||||||
|
\end{document}
|
||||||
@ -0,0 +1,156 @@
|
|||||||
|
{% load tex_extras %}
|
||||||
|
|
||||||
|
\documentclass{article}
|
||||||
|
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
\usepackage{booktabs}
|
||||||
|
\usepackage{amssymb}
|
||||||
|
\usepackage{cmbright}
|
||||||
|
\usepackage{graphicx}
|
||||||
|
\usepackage{textpos}
|
||||||
|
\usepackage[colorlinks, breaklinks]{hyperref}
|
||||||
|
\usepackage{float}
|
||||||
|
\usepackage[margin=1in]{geometry}
|
||||||
|
\usepackage{array}
|
||||||
|
\usepackage{ragged2e}
|
||||||
|
\usepackage{tabularx}
|
||||||
|
\usepackage{titlesec}
|
||||||
|
|
||||||
|
\titleformat{\section}
|
||||||
|
{\Large\slshape}{\thesection\;}
|
||||||
|
{0em}{}
|
||||||
|
|
||||||
|
\newcommand{\picpos}[4]{
|
||||||
|
\begin{textblock*}{#1}(#2, #3)
|
||||||
|
\includegraphics[width=\textwidth]{#4}
|
||||||
|
\end{textblock*}
|
||||||
|
}
|
||||||
|
|
||||||
|
% custom url command for properly formatting emails
|
||||||
|
\DeclareUrlCommand\Email{\urlstyle{same}}
|
||||||
|
% allow linebreak after every character
|
||||||
|
\expandafter\def\expandafter\UrlBreaks\expandafter{\UrlBreaks
|
||||||
|
\do\/\do\a\do\b\do\c\do\d\do\e\do\f\do\g\do\h\do\i\do\j\do\k
|
||||||
|
\do\l\do\m\do\n\do\o\do\p\do\q\do\r\do\s\do\t\do\u\do\v
|
||||||
|
\do\w\do\x\do\y\do\z
|
||||||
|
\do\A\do\B\do\C\do\D\do\E\do\F\do\G\do\H\do\I\do\J\do\K
|
||||||
|
\do\L\do\M\do\N\do\O\do\P\do\Q\do\R\do\S\do\T\do\U\do\V
|
||||||
|
\do\W\do\X\do\Y\do\Z}
|
||||||
|
|
||||||
|
\renewcommand{\arraystretch}{1.5}
|
||||||
|
|
||||||
|
\newcolumntype{L}{>{\hspace{0pt}}X}
|
||||||
|
\newcolumntype{Y}{>{\RaggedRight\arraybackslash}X}
|
||||||
|
\newcommand{\tickedbox}{
|
||||||
|
\makebox[0pt][l]{$\square$}\raisebox{.15ex}{\hspace{0.1em}$\checkmark$}
|
||||||
|
}
|
||||||
|
\newcommand{\checkbox}{
|
||||||
|
\makebox[0pt][l]{$\square$}
|
||||||
|
}
|
||||||
|
\begin{document}
|
||||||
|
% HEADER RIGHT
|
||||||
|
\picpos{4.5cm}{11.5cm}{0cm}{dav_logo.png}
|
||||||
|
\begin{textblock*}{5cm}(11.5cm, 2.3cm)
|
||||||
|
\begin{flushright}
|
||||||
|
\small
|
||||||
|
\noindent Deutscher Alpenverein e. V. \\
|
||||||
|
Sektion Ludwigsburg\\
|
||||||
|
Fuchshofstr. 66\\
|
||||||
|
71638 Ludwigsburg\\
|
||||||
|
Tel.: 07141 927893\\
|
||||||
|
Fax: 07141 924042\\
|
||||||
|
info@alpenverein-ludwigsburg.de\\
|
||||||
|
\end{flushright}
|
||||||
|
\end{textblock*}
|
||||||
|
|
||||||
|
% HEADLINE
|
||||||
|
{\noindent\LARGE{Seminarbericht}}\\[1mm]
|
||||||
|
\textit{Erstellt: {{ creation_date }} }\\
|
||||||
|
|
||||||
|
% DESCRIPTION TABLE
|
||||||
|
\begin{table}[H]
|
||||||
|
\begin{tabular}{ll}
|
||||||
|
\large Kursname: & {% if not memberlist.ljpproposal %}{{ memberlist.name|esc_all }}{% else %}{{ memberlist.ljpproposal.title }} {% endif %} \\
|
||||||
|
\large Gruppe: & {{ memberlist.groups_str|esc_all }} \\
|
||||||
|
\large Ziel: & {{ memberlist.place|esc_all }} \\
|
||||||
|
\large Stützpunkt: & {{ memberlist.destination|esc_all }} \\
|
||||||
|
\large Zeitraum: & {{ memberlist.time_period_str|esc_all }} \\
|
||||||
|
\large Betreuer:innen: & {{ memberlist.staff_str|esc_all }} \\
|
||||||
|
\end{tabular}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
{% if memberlist.ljpproposal %}
|
||||||
|
|
||||||
|
\section{Alpine Ziele}
|
||||||
|
|
||||||
|
{{ memberlist.ljpproposal.goals_alpinistic|esc_all }}
|
||||||
|
|
||||||
|
\section{Pädagogische Ziele}
|
||||||
|
|
||||||
|
{{ memberlist.ljpproposal.goals_pedagogic|esc_all }}
|
||||||
|
|
||||||
|
\section{Inhalt und Methoden}
|
||||||
|
|
||||||
|
{{ memberlist.ljpproposal.methods|esc_all }}
|
||||||
|
|
||||||
|
\section{Evaluation}
|
||||||
|
|
||||||
|
{{ memberlist.ljpproposal.evaluation|esc_all }}
|
||||||
|
|
||||||
|
\section{Erfahrungen und mögliche Verbesserungsvorschläge}
|
||||||
|
|
||||||
|
{{ memberlist.ljpproposal.experiences|esc_all }}
|
||||||
|
|
||||||
|
\section{Methodischer Ablauf}
|
||||||
|
|
||||||
|
\begin{table}[H]
|
||||||
|
\begin{tabularx}{1\linewidth}{@{}l l Y @{}}
|
||||||
|
\toprule
|
||||||
|
\textbf{Zeitpunkt} & \textbf{Dauer} & \textbf{Aktivität und Methode} \\
|
||||||
|
\midrule
|
||||||
|
{% for intervention in memberlist.ljpproposal.intervention_set.all %}
|
||||||
|
{{ intervention.date_start|datetime_short }} & {{ intervention.duration }} h & {{ intervention.activity|esc_all }} \\
|
||||||
|
{% endfor %}
|
||||||
|
\bottomrule
|
||||||
|
\end{tabularx}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
\section{Teilnehmer:innenliste}
|
||||||
|
|
||||||
|
\begin{table}[H]
|
||||||
|
\begin{tabularx}{1\linewidth}{@{\extracolsep{\fill}}lLl|l|l|l}
|
||||||
|
\hline
|
||||||
|
\textbf{Name} & \textbf{Anschrift} & \textbf{Geburtsdatum} & \textbf{m} & \textbf{w} & \textbf{d} \\ \hline
|
||||||
|
%\midrule
|
||||||
|
{% for m in memberlist.membersonlist.all %}
|
||||||
|
{{ m.member.name|esc_all }} & {{ m.member.address|esc_all }} & {{ m.member.birth_date_str|esc_all }} & & & \\
|
||||||
|
{% endfor %}
|
||||||
|
%\bottomrule
|
||||||
|
\end{tabularx}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
{% if memberlist.statement %}
|
||||||
|
|
||||||
|
\section{Kosten}
|
||||||
|
|
||||||
|
\begin{table}[H]
|
||||||
|
\begin{tabularx}{1\linewidth}{@{}L r @{}}
|
||||||
|
\toprule
|
||||||
|
\textbf{Beschreibung} & \textbf{Betrag} \\
|
||||||
|
\midrule
|
||||||
|
Aufwandsentschädigung & {{ memberlist.statement.total_allowance }} € \\
|
||||||
|
Fahrtkosten & {{ memberlist.statement.total_transportation }} € \\
|
||||||
|
Übernachtungskosten & {{ memberlist.statement.total_nights }} € \\
|
||||||
|
{% for bill in memberlist.statement.bill_set.all %}
|
||||||
|
{{ bill.short_description|esc_all }} & {{ bill.amount }} € \\
|
||||||
|
{% endfor %}
|
||||||
|
\bottomrule
|
||||||
|
Gesamt & {{ memberlist.statement.total_theoretic }} € \\
|
||||||
|
\end{tabularx}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
\end{document}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
from django import template
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def checked_if_true(name, value):
|
||||||
|
if name == value:
|
||||||
|
return '\\tickedbox {} \qquad \qquad'.format(name)
|
||||||
|
else:
|
||||||
|
return '\\checkbox \\enspace \\enspace {} \qquad \qquad'.format(name)
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def esc_all(val):
|
||||||
|
return mark_safe(str(val).replace('_', '\\_').replace('&', '\\&'))
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def datetime_short(date):
|
||||||
|
return date.strftime('%d.%m.%Y %H:%M')
|
||||||
Loading…
Reference in New Issue