/
autor.py
221 lines (188 loc) · 8.9 KB
/
autor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
from copy import copy
from django.http import HttpResponse, HttpResponseRedirect
from django.template.defaultfilters import pluralize
from django.urls import reverse
from django.views.generic import FormView, TemplateView
from django_tables2 import MultiTableMixin, RequestConfig
from django_weasyprint.utils import django_url_fetcher
from formdefaults.helpers import FormDefaultsMixin
from raport_slotow.forms import AutorRaportSlotowForm
from raport_slotow.tables import RaportSlotowAutorTable
from raport_slotow.util import InitialValuesFromGETMixin, MyExportMixin, MyTableExport
from .. import const
from django.utils import timezone
from django.utils.functional import cached_property
from bpp.models import Cache_Punktacja_Autora_Query_View, Dyscyplina_Naukowa
from bpp.views.mixins import UczelniaSettingRequiredMixin
from django_bpp.version import VERSION
SESSION_KEY = "raport_slotow_data"
class WyborOsoby(
UczelniaSettingRequiredMixin, InitialValuesFromGETMixin, FormDefaultsMixin, FormView
):
template_name = "raport_slotow/wybor_osoby.html"
form_class = AutorRaportSlotowForm
uczelnia_attr = "pokazuj_raport_slotow_autor"
title = "Raport slotów - autor"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["title"] = "Wybór autora"
return context
def form_valid(self, form):
form.cleaned_data["obiekt"] = form.cleaned_data["obiekt"].pk
self.request.session[SESSION_KEY] = form.cleaned_data
return HttpResponseRedirect(
reverse("raport_slotow:raport") + "?_export=" + form.cleaned_data["_export"]
)
class RaportSlotow(
UczelniaSettingRequiredMixin, MyExportMixin, MultiTableMixin, TemplateView
):
template_name = "raport_slotow/raport_slotow_autor.html"
table_class = RaportSlotowAutorTable
uczelnia_attr = "pokazuj_raport_slotow_autor"
export_formats = ["html", "xlsx", "pdf"]
export_class = MyTableExport
def create_export(self, export_format):
tables = self.get_tables()
n = int(self.request.GET.get("n", 0))
dg = []
dpb = []
for ad in self.autor.autor_dyscyplina_set.filter(
rok__range=(self.kwargs["od_roku"], self.kwargs["do_roku"])
).order_by("rok"):
dg.append((ad.rok, ad.dyscyplina_naukowa.nazwa, ad.procent_dyscypliny))
if ad.subdyscyplina_naukowa is not None:
dpb.append(
(ad.rok, ad.subdyscyplina_naukowa.nazwa, ad.procent_subdyscypliny)
)
dg = ", ".join([f"{rok} - {nazwa} ({procent})" for rok, nazwa, procent in dg])
dpb = ", ".join([f"{rok} - {nazwa} ({procent})" for rok, nazwa, procent in dpb])
description = [
("Nazwa raportu:", "raport slotów - autor"),
("Autor:", str(self.autor)),
("ORCID:", str(self.autor.orcid or "brak")),
("PBN ID:", str(self.autor.pbn_id or "brak")),
("Dyscypliny autora:", dg),
("Subdyscypliny autora:", dpb or "żadne"),
("Dyscyplina tabeli:", str(tables[n].dyscyplina_naukowa or "żadna")),
("Opis działania", self.opis_dzialania),
("Minimalny PK", self.kwargs["minimalny_pk"]),
("Od roku:", self.kwargs["od_roku"]),
("Do roku:", self.kwargs["do_roku"]),
("Wygenerowano:", timezone.now()),
("Wersja oprogramowania BPP", VERSION),
]
exporter = MyTableExport(
export_format=export_format,
table=tables[n],
export_description=description,
)
return exporter.response(filename=self.get_export_filename(export_format, n))
def get_tables(self):
ret = []
cpaq = Cache_Punktacja_Autora_Query_View.objects.filter(
autor=self.autor,
rekord__rok__gte=self.kwargs["od_roku"],
rekord__rok__lte=self.kwargs["do_roku"],
pkdaut__gt=0,
)
minimalny_pk = self.kwargs["minimalny_pk"]
for elem in cpaq.values_list("dyscyplina", flat=True).order_by().distinct():
table_class = self.table_class
if self.kwargs["dzialanie"] == const.DZIALANIE_WSZYSTKO:
data = cpaq.filter(dyscyplina_id=elem)
if minimalny_pk is not None:
data = data.filter(rekord__punkty_kbn__gte=minimalny_pk)
elif self.kwargs["dzialanie"] == const.DZIALANIE_SLOT:
max_pkdaut, ids, maks_slot = self.autor.zbieraj_sloty(
self.kwargs["slot"],
self.kwargs["od_roku"],
self.kwargs["do_roku"],
dyscyplina_id=elem,
minimalny_pk=minimalny_pk,
)
data = cpaq.filter(pk__in=ids)
else:
raise NotImplementedError()
table = table_class(
data.select_related(
"rekord",
"dyscyplina",
).prefetch_related("rekord__zrodlo")
)
RequestConfig(
self.request, paginate=self.get_table_pagination(table)
).configure(table)
table.dyscyplina_naukowa = Dyscyplina_Naukowa.objects.get(pk=elem)
ret.append(table)
if not ret:
table_class = self.table_class
table = table_class(data=cpaq.select_related("rekord", "dyscyplina"))
RequestConfig(
self.request, paginate=self.get_table_pagination(table)
).configure(table)
table.dyscyplina_naukowa = None
ret.append(table)
return ret
def get_queryset(self):
return None
@cached_property
def opis_dzialania(self):
if self.kwargs["dzialanie"] == const.DZIALANIE_WSZYSTKO:
return "wszystkie rekordy z punktacją dla dyscyplin za dany okres"
elif self.kwargs["dzialanie"] == const.DZIALANIE_SLOT:
return f"zbieranie najlepszych prac do {self.kwargs['slot']} slot{pluralize(self.kwargs['slot'], 'u,ów')}"
else:
raise NotImplementedError
def get_context_data(self, *, cleaned_data=None, object_list=None, **kwargs):
context = super(RaportSlotow, self).get_context_data(**kwargs)
context["autor"] = self.autor
context["od_roku"] = self.kwargs["od_roku"]
context["do_roku"] = self.kwargs["do_roku"]
context["minimalny_pk"] = self.kwargs["minimalny_pk"]
context["slot"] = self.kwargs["slot"]
context["dzialanie"] = self.kwargs["dzialanie"]
context["opis_dzialania"] = self.opis_dzialania
return context
def get_export_filename(self, export_format, n):
return f"raport_slotow_{self.autor.slug}_{self.kwargs['od_roku']}-{self.kwargs['do_roku']}-{n}.{export_format}"
def get(self, request, *args, **kwargs):
# Wczytaj dane z sesji i zwaliduj przez formularz
data = request.session.get(SESSION_KEY)
form = AutorRaportSlotowForm(data)
if form.is_valid():
self.kwargs.update(form.cleaned_data)
self.autor = self.kwargs["obiekt"]
export_format = self.request.GET.get(self.export_trigger_param, None)
if export_format in ["xlsx", "html", None]:
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
elif export_format == "pdf":
new_get = copy(self.request.GET)
new_get["_export"] = "html"
self.request.GET = new_get
context = self.get_context_data(**kwargs)
ret = self.render_to_response(context)
# UWAGA: jeżeli w wygenerowanej stronie WWW cokolwiek będzie dostępne
# za hasłem, to może się ona nie wygenerować prawidłowo. Żeby wyrenderować
# PDFa, serwer wstecznie odpytuje sam siebie - o CSSy, obrazki, fonty itp.
# Jeżeli nagle będziemy mieli jakis zahasłowany statyczny asset, to będzie
# trzeba go tutaj udostępnić, żeby WeasyPrint miał ułatwione zadanie.
# (mpasternak, 17.03.2021)
from weasyprint import HTML
response = HttpResponse(
content=HTML(
string=ret.render().content,
base_url=self.request.build_absolute_uri(),
url_fetcher=django_url_fetcher,
).write_pdf(),
content_type="application/pdf",
)
filename = self.get_export_filename("pdf", 0)
response["Content-Disposition"] = f'attachment; filename="{filename}"'
return response
else:
raise NotImplementedError(
f"unknown format {export_format}, also this should never happen"
)
else:
return HttpResponseRedirect("..")