members/admin: use pdf module for membernotelist, cleanup

jenkins
Christian Merten 3 years ago
parent a86f6ff584
commit e62f5c7ee0
Signed by: christian.merten
GPG Key ID: D953D69721B948B3

@ -533,76 +533,51 @@ class MemberNoteListAdmin(admin.ModelAdmin):
list_display = ['__str__', 'date'] list_display = ['__str__', 'date']
search_fields = ('name',) search_fields = ('name',)
ordering = ('-date',) ordering = ('-date',)
actions = ['generate_summary'] actions = ['summary']
def generate_summary(self, request, queryset): def get_urls(self):
"""Generates a pdf summary of the given NoteMemberLists urls = super().get_urls()
"""
for memberlist in queryset: def wrap(view):
# unique filename def wrapper(*args, **kwargs):
filename = memberlist.title + "_notes_" + datetime.today().strftime("%d_%m_%Y") return self.admin_site.admin_view(view)(*args, **kwargs)
filename = filename.replace(' ', '_').replace('&', '').replace('/', '_')
# drop umlauts, accents etc. wrapper.model_admin = self
filename = unicodedata.normalize('NFKD', filename).\ return update_wrapper(wrapper, view)
encode('ASCII', 'ignore').decode()
filename_tex = filename + '.tex' custom_urls = [
filename_pdf = filename + '.pdf' path(
"<path:object_id>/action/",
# generate table wrap(self.action_view),
table = "" name="%s_%s_action" % (self.opts.app_label, self.opts.model_name),
for memberonlist in memberlist.membersonlist.all(): ),
m = memberonlist.member ]
comment = ". ".join(c for c return custom_urls + urls
in (m.comments,
memberonlist.comments) if def action_view(self, request, object_id):
c).replace("..", ".") if "summary" in request.POST:
line = '{0} {1} & {2} \\\\'.format( return self.summary(request, [MemberNoteList.objects.get(pk=object_id)])
esc_ampersand(m.prename), esc_ampersand(m.lastname), return HttpResponseRedirect(reverse('admin:%s_%s_change' % (self.opts.app_label, self.opts.model_name),
esc_ampersand(comment) or "---") args=(object_id,)))
table += esc_underscore(line)
def may_view_notelist(self, request, memberlist):
# copy template return request.user.has_perm('members.may_view_everyone') or \
shutil.copy(media_path('memberlistnote_template.tex'), ( hasattr(request.user, 'member') and \
media_path(filename_tex)) all([request.user.member.may_view(m.member) for m in memberlist.membersonlist.all()]) )
# read in template def not_allowed_view(self, request, memberlist):
with open(media_path(filename_tex), 'r', encoding='utf-8') as f: messages.error(request,
template_content = f.read() _("You are not allowed to view all members on note list %(name)s.") % {'name': memberlist.title})
return HttpResponseRedirect(reverse('admin:%s_%s_changelist' % (self.opts.app_label, self.opts.model_name)))
# adapt template
title = esc_all(memberlist.title) def summary(self, request, queryset):
template_content = template_content.replace('MEMBERLIST-TITLE', title) # this ensures legacy compatibilty
template_content = template_content.replace('MEMBERLIST-DATE', memberlist = queryset[0]
datetime.today().strftime('%d.%m.%Y')) if not self.may_view_notelist(request, memberlist):
template_content = template_content.replace('TABLE', table) return self.not_allowed_view(request, memberlist)
context = dict(memberlist=memberlist, settings=settings)
# write adapted template to file return render_tex(memberlist.title + "_Zusammenfassung", 'members/notelist_summary.tex', context)
with open(media_path(filename_tex), 'w', encoding='utf-8') as f: summary.short_description = _('Generate PDF summary')
f.write(template_content)
# compile using pdflatex
oldwd = os.getcwd()
os.chdir(media_dir())
subprocess.call(['pdflatex', 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.chdir(oldwd)
# provide the user with the resulting pdf file
with open(media_path(filename_pdf), 'rb') as pdf:
response = HttpResponse(FileWrapper(pdf))
response['Content-Type'] = 'application/pdf'
response['Content-Disposition'] = 'attachment; filename=' + filename_pdf
return response
generate_summary.short_description = "PDF Übersicht erstellen"
class FreizeitAdmin(CommonAdminMixin, nested_admin.NestedModelAdmin): class FreizeitAdmin(CommonAdminMixin, nested_admin.NestedModelAdmin):
@ -773,23 +748,3 @@ admin.site.register(MemberNoteList, MemberNoteListAdmin)
admin.site.register(Klettertreff, KlettertreffAdmin) admin.site.register(Klettertreff, KlettertreffAdmin)
admin.site.register(ActivityCategory, ActivityCategoryAdmin) admin.site.register(ActivityCategory, ActivityCategoryAdmin)
admin.site.register(TrainingCategory, TrainingCategoryAdmin) admin.site.register(TrainingCategory, TrainingCategoryAdmin)
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 esc_underscore(txt):
return txt.replace('_', '\_')
def esc_ampersand(txt):
return txt.replace('&', '\&')
def esc_all(txt):
return esc_underscore(esc_ampersand(txt))

@ -0,0 +1,38 @@
{% 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\textsc{ {{ memberlist.title|esc_all }} }}\\
\textit{Erstellt: {{ creation_date }} }\\
\begin{table}[H]
\begin{tabularx}{\textwidth}{@{} l l Y @{}}
\toprule
\textbf{Name} & \textbf{Kommentare} \\
\midrule
{% for m in memberlist.membersonlist.all %}
{{ m.member.name|esc_all }} & {{ m.comments_tex|esc_all }} \\
{% endfor %}
\bottomrule
\end{tabularx}
\end{table}
\end{document}
Loading…
Cancel
Save