aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Lepori <aleporia@gmail.com>2024-11-12 15:27:12 +0100
committerAndrea Lepori <aleporia@gmail.com>2024-11-12 15:27:23 +0100
commit0b5be72725ffd6cd10490fbd202388e22c7f8522 (patch)
treeaa3738e82a99372468084885aa7cbbbf1ef83fcd
parentadd new materialize v2 (diff)
downloadscout-subs-data_download.tar.gz
scout-subs-data_download.zip
commit edits for new featuredata_download
-rw-r--r--requirements.txt1
-rw-r--r--server/templates/server/data_download.html102
-rw-r--r--server/templates/server/doc_type.html2
-rw-r--r--server/urls.py2
-rw-r--r--server/views.py84
-rw-r--r--templates/registration/base_admin.html5
-rw-r--r--version.txt2
7 files changed, 195 insertions, 3 deletions
diff --git a/requirements.txt b/requirements.txt
index 05c1064..99eaa57 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,3 +8,4 @@ django-debug-toolbar
requests
authlib
django-impersonate
+pypdf
diff --git a/server/templates/server/data_download.html b/server/templates/server/data_download.html
new file mode 100644
index 0000000..59b180d
--- /dev/null
+++ b/server/templates/server/data_download.html
@@ -0,0 +1,102 @@
+{% extends 'registration/base_admin.html' %}
+
+{% block title %}Admin - Richiesta dati{% endblock %}
+
+{% block breadcrumb %}
+ <a href="{% url 'server'%}" class="breadcrumb hide-on-med-and-down">Admin</a>
+ <a class="breadcrumb hide-on-med-and-down">Richiesta dati</a>
+{% endblock %}
+
+{% block content %}
+
+<div class="row">
+ <div class="col l4 offset-l4 m8 offset-m2 s12">
+ <div class="card">
+ <div class="card-content">
+ <div class="row">
+ <div class="col s12">
+ <div class="chips" id="doc_search"></div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col s12">
+ <p>
+ <label>
+ <input class="filled-in" name="personal" type="checkbox"/>
+ <span>Dati personali</span>
+ </label>
+ </p>
+ <p>
+ <label>
+ <input class="filled-in" name="medic" type="checkbox"/>
+ <span>Dati medici</span>
+ </label>
+ </p>
+ <p>
+ <label>
+ <input class="filled-in" name="attachments" type="checkbox"/>
+ <span>Allegati (vaccinazioni e tessera cassa malati)</span>
+ </label>
+ </p>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col s12">
+ <a onclick="send()" class="waves-effect waves-light btn {{color}}"><i class="material-icons left">download</i>Scarica</a>
+ </div>
+ </div>
+ <div class="row" id="loading" hidden>
+ <div class="col s12">
+ <h6 id="progress_text">Preparazione dei documenti</h6>
+ <div class="progress">
+ <div id="progress_bar" class="indeterminate"></div>
+ <div class="determinate" style="width: 0%"></div>
+ </div>
+ <p id="under_text"></p>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+{% endblock %}
+
+{% block script %}
+$(document).ready(function(){
+ {% if error %}
+ M.toast({html: '{{ error }}', classes: 'orange'})
+ {% endif %}
+});
+
+document.addEventListener('DOMContentLoaded', function() {
+ var options = {
+ placeholder: 'Documento',
+ autocompleteOptions: {
+ data: {
+ {% for doc in docs %}
+ '{{ doc.name }}': null,
+ {% endfor %}
+ },
+ },
+ limit: 1,
+ };
+
+ var elems = document.querySelectorAll('.chips');
+ var instances = M.Chips.init(elems, options);
+});
+
+function send() {
+ var chips = M.Chips.getInstance(document.getElementById('doc_search'));
+ var personal = document.getElementsByName('personal')[0].checked;
+ var medic = document.getElementsByName('medic')[0].checked;
+ var attachments = document.getElementsByName('attachments')[0].checked;
+
+ var loadbox = document.getElementById('loading');
+ var progress = document.getElementById('progress_bar');
+ var progress_text = document.getElementById('progress_text');
+ var under_text = document.getElementById('under_text');
+
+ loadbox.hidden = false;
+
+}
+{% endblock%} \ No newline at end of file
diff --git a/server/templates/server/doc_type.html b/server/templates/server/doc_type.html
index 35dd9f3..023ea5e 100644
--- a/server/templates/server/doc_type.html
+++ b/server/templates/server/doc_type.html
@@ -147,7 +147,7 @@
<div class="collapsible-body"><span>
<div class="hide-on-med-and-down">
<a class="waves-effect waves-light btn {{color}}" onclick="send('e{{doctype.id}}')"><i class="material-icons left">edit</i>Modifica tipo</a>
- <a class="waves-effect waves-light btn {{color}}" onclick="send('p{{doctype.id}}')"><i class="material-icons left">file_download</i>Scarica CSV</a>
+ <a class="waves-effect waves-light btn {{color}}" onclick="send('d{{doctype.id}}')"><i class="material-icons left">file_download</i>Scarica CSV</a>
{% if doctype.medical_data %}
<a class="waves-effect waves-light btn {{color}}" onclick="send('m{{doctype.id}}')"><i class="material-icons left">download_for_offline</i>Scarica CSV (con dati medici)</a>
{% endif %}
diff --git a/server/urls.py b/server/urls.py
index 5937707..7906dfa 100644
--- a/server/urls.py
+++ b/server/urls.py
@@ -22,5 +22,7 @@ urlpatterns = [
path('progress', views.get_progress, name='progress'),
path('request', views.data_request, name='request'),
path('debug-uc', views.debug_uc, name='debug-uc'),
+ path('download-data', views.download_data, name='download-data'),
+ path('data-progress', views.download_data_progress, name='data-progress'),
path('media/<int:id>/<str:t>/<str:flag>', views.media_request, name='media'),
]
diff --git a/server/views.py b/server/views.py
index ef13e45..b9e2dc7 100644
--- a/server/views.py
+++ b/server/views.py
@@ -28,6 +28,7 @@ from PIL import Image, UnidentifiedImageError
import zipfile
import json
import threading
+from pypdf import PdfMerger
# custom staff check function for non primary group staff members
def isStaff(user):
@@ -416,7 +417,7 @@ def ulist(request):
# get template and build context
template = get_template('server/download_doc.html')
doc = [document, KeyVal.objects.filter(
- container=document), document.personal_data, document.medical_data, document.user.groups.values_list('name', flat=True)[0]]
+ container=document), document.personal_data, document.medical_data]
context = {'doc': doc, 'vac': vac_file,
'health': health_file, 'sign_doc_file': sign_doc_file}
# render context
@@ -1899,6 +1900,87 @@ def debug_uc(request):
return render(request, 'server/debug_usercode.html', context)
@user_passes_test(isStaff)
+def download_data(request):
+ groups = getGroups(request)
+
+ # get all doctypes the user has access to
+ doctypes = DocumentType.objects.filter(group__in=groups)
+ # sort by name
+ doctypes = doctypes.order_by("name")
+
+ context = {
+ "docs": doctypes
+ }
+
+ return render(request, 'server/data_download.html', context)
+
+def download_data_progress(request):
+ # if user wants to download result
+ if 'download' in request.GET:
+ # if job is completed
+ if request.session['status']:
+ data = BytesIO(base64.b64decode(request.session['result']))
+ data.seek(0)
+ return FileResponse(data, as_attachment=True, filename="documents_" + datetime.now().strftime("%H_%M-%d_%m_%y") + ".pdf")
+
+ # otherwise return status
+ data = [request.session['progress'], request.session['total'], request.session['status']]
+ return HttpResponse(json.dumps(data))
+
+def prepare_documents(docs, session_key):
+ pdf_list = []
+
+ # get session
+ session = SessionStore(session_key=session_key)
+ for i in docs:
+ vac_file = ""
+ health_file = ""
+ sign_doc_file = ""
+
+ # prepare pictures in base64
+ if i.medical_data:
+ if i.medical_data.vac_certificate.name:
+ with open(i.medical_data.vac_certificate.name, 'rb') as image_file:
+ vac_file = base64.b64encode(
+ image_file.read()).decode()
+
+ if i.medical_data.health_care_certificate.name:
+ with open(i.medical_data.health_care_certificate.name, 'rb') as image_file:
+ health_file = base64.b64encode(
+ image_file.read()).decode()
+ if i.signed_doc:
+ with open(i.signed_doc.name, 'rb') as image_file:
+ sign_doc_file = base64.b64encode(
+ image_file.read()).decode()
+
+ template = get_template('server/download_doc.html')
+ doc = [i, KeyVal.objects.filter(
+ container=i), i.personal_data, i.medical_data]
+ context = {'doc': doc, 'vac': vac_file,
+ 'health': health_file, 'sign_doc_file': sign_doc_file}
+ # render context
+ html = template.render(context)
+ # render pdf using wkhtmltopdf
+ pdf = pdfkit.from_string(html, False)
+ # append file
+ pdf_list.append(pdf)
+
+ session['progress'] += 1
+ session.save()
+
+ merger = PdfMerger()
+ for pdf in pdf_list:
+ merger.append(BytesIO(pdf))
+
+ mem = BytesIO()
+ merger.write(mem)
+ mem.seek(0)
+ # save result
+ session['result'] = base64.b64encode(mem.getvalue()).decode()
+ session['status'] = True
+ session.save()
+
+@user_passes_test(isStaff)
def data_request(request):
context = {}
parent_group = getGroups(request)[0]
diff --git a/templates/registration/base_admin.html b/templates/registration/base_admin.html
index 9643e35..c414fea 100644
--- a/templates/registration/base_admin.html
+++ b/templates/registration/base_admin.html
@@ -19,6 +19,11 @@
box-shadow: 0 1px 0 0 {{hexcolor}} !important;
}
+ .chips.focus {
+ border-bottom: 1px solid {{hexcolor}} !important;
+ box-shadow: 0 1px 0 0 {{hexcolor}} !important;
+ }
+
input[type=password]:focus, .materialize-textarea:focus:not([readonly]) {
border-bottom: 1px solid {{hexcolor}} !important;
box-shadow: 0 1px 0 0 {{hexcolor}} !important;
diff --git a/version.txt b/version.txt
index c0053a4..153f555 100644
--- a/version.txt
+++ b/version.txt
@@ -1,2 +1,2 @@
version=0.7
-rev=26
+rev=27