diff options
-rw-r--r-- | server/templates/server/doc_list.html | 49 | ||||
-rw-r--r-- | server/urls.py | 4 | ||||
-rw-r--r-- | server/views.py | 126 |
3 files changed, 133 insertions, 46 deletions
diff --git a/server/templates/server/doc_list.html b/server/templates/server/doc_list.html index 986b683..2159130 100644 --- a/server/templates/server/doc_list.html +++ b/server/templates/server/doc_list.html @@ -36,7 +36,7 @@ </li> <li><a class="tooltipped modal-trigger" href="#modal2" data-position="top" data-tooltip="Archivia selezionati"><i class="material-icons">archive</i></a></li> <li><a class="tooltipped" data-position="top" data-tooltip="Dearchivia selezionati" Onclick="send('unarchive')"><i class="material-icons">unarchive</i></a></li> - <li><a class="tooltipped" data-position="top" data-tooltip="Scarica selezionati" Onclick="send('download')"><i class="material-icons">file_download</i></a></li> + <li><a class="tooltipped modal-trigger" href="#modal3" data-position="top" data-tooltip="Scarica selezionati" Onclick="send('download')"><i class="material-icons">file_download</i></a></li> {% if settings.DEBUG %} <li><a class="tooltipped" data-position="top" data-tooltip="Approva selezionati" Onclick="send('approve')"><i class="material-icons left">check</i>DEBUG</a></li> <li><a class="tooltipped" data-position="top" data-tooltip="Elimina selezionati" Onclick="send('delete')"><i class="material-icons left">delete</i>DEBUG</a></li> @@ -65,6 +65,17 @@ </div> </div> +<div id="modal3" class="modal"> + <div class="modal-content"> + <h5>Preparazione dei documenti</h5> + <div class="progress"> + <div id="progress_bar" class="indeterminate"></div> + <div class="determinate" style="width: 0%"></div> + </div> + <p id="progress_text"></p> + </div> +</div> + <form id="selection" action="{% url 'doclist' %}" method="post"> {% csrf_token %} <div id="modal1" class="modal"> @@ -464,6 +475,11 @@ $(document).ready(function(){ {% if error %} M.toast({html: '{{ error_text}}', classes: 'orange'}) {% endif %} + {% if task_id %} + $('#modal3').modal('open'); + update(); + document.getElementById('progress_bar').className = "determinate"; + {% endif %} }); $('.chips').chips(); @@ -522,6 +538,37 @@ $('#chips_groups').chips({ ] }); +function update() { + var box = document.getElementById('progress_text'); + var bar = document.getElementById('progress_bar'); + {% if task_id %} + var url = '{% url "progress" %}' + '?job=' + '{{task_id}}'; + {% else %} + var url = '{% url "progress" %}'; + {% endif %} + fetch(url).then(function(response) { + response.json().then(function(data) { + if (data[0] == data[1]) { + if (data[2]) { + bar.className = "indeterminate"; + var url = '{% url "progress" %}' + '?job=' + '{{task_id}}' + '&download=true'; + box.innerHTML = "Il download dovrebbe partire automaticamente. Nel caso non succedesse cliccare il seguente <a id='downloadLink' href=" + url + ">link</a>"; + document.getElementById('downloadLink').click(); + + } else { + bar.style.width = "100%"; + box.innerHTML = "Impacchettamento documenti..."; + setTimeout(update, 500, url); + } + } else { + box.innerHTML = data[0] + "/" + data[1]; + bar.style.width = data[0]/data[1]*100 + "%"; + setTimeout(update, 500, url); + } + }); + }); +} + function send(id) { var form = document.getElementById('selection') var action = document.getElementById('action') diff --git a/server/urls.py b/server/urls.py index 0be590c..b744730 100644 --- a/server/urls.py +++ b/server/urls.py @@ -1,7 +1,8 @@ -from django.urls import path +from django.urls import path, re_path, include from . import views + urlpatterns = [ path('', views.index, name='server'), path('uapprove', views.uapprove, name='uapprove'), @@ -12,4 +13,5 @@ urlpatterns = [ path('docapprove', views.docapprove, name='docapprove'), path('docupload', views.upload_doc, name='docupload'), path('docpreview', views.docpreview, name='docpreview'), + path('progress', views.get_progress, name='progress'), ] diff --git a/server/views.py b/server/views.py index 250feec..e8fbe8b 100644 --- a/server/views.py +++ b/server/views.py @@ -20,7 +20,11 @@ import os import base64 from PIL import Image, UnidentifiedImageError import zipfile +import json +import threading +import random +progress = {} # custom staff check function for non primary group staff members def isStaff(user): @@ -152,7 +156,6 @@ def docapprove(request): data = data.split("\n") # check if code valid for i in range(len(data)): - print(Document.objects.filter(code=data[i])[0].group.name) if not data[i].isdigit(): data[i] = data[i] + " - Formato errato" elif int(data[i]) < 100000 or int(data[i]) > 999999: @@ -615,8 +618,6 @@ def doclist(request): if docc.group.name in parent_groups: selected.append(docc) - # create list of pdfs - files = [] # execute action on selected documents for i in selected: if request.POST["action"] == 'delete' and settings.DEBUG: @@ -641,48 +642,10 @@ def doclist(request): else: error = True error_text = "Non puoi dearchiviare un documento non archiviato" - elif request.POST["action"] == "download": - 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, i.user.groups.values_list('name', flat=True)[0]] - 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) - filename = i.user.username+"_"+i.document_type.name+".pdf" - files.append((filename, pdf)) - - if request.POST["action"] == "download": - mem_zip = BytesIO() - - with zipfile.ZipFile(mem_zip, mode="w",compression=zipfile.ZIP_DEFLATED) as zf: - for f in files: - zf.writestr(f[0], f[1]) - mem_zip.seek(0) - return FileResponse(mem_zip, as_attachment=True, filename="documents_" + datetime.now().strftime("%H_%M-%d_%m_%y") + ".zip") + if len(selected) == 0: + error = True + error_text = "Seleziona almeno un documento" # get filter values hidden = "filter_hidden" in request.POST @@ -824,8 +787,83 @@ def doclist(request): 'error_text': error_text, 'settings': settings, } + + if request.method == "POST": + if request.POST["action"] == "download" and len(selected) > 0: + code = request.user.username + "_" + str(random.randint(100, 999)) + progress[code] = [0, 0, False, request.user, None] + threading.Thread(target=zip_documents, args=(selected, code)).start() + context["task_id"] = code + return render(request, 'server/doc_list.html', context) +def get_progress(request): + if 'job' in request.GET: + job_id = request.GET['job'] + else: + return HttpResponse(json.dumps({"error": True})) + + if not job_id in progress.keys(): + return HttpResponse(json.dumps({"error": "Lavoro non esistente. Provare a richiedere di nuovo il lavoro."})) + + if 'download' in request.GET: + if progress[job_id][3] == request.user: + data = progress[job_id][4] + del progress[job_id] + return data + data = progress[job_id][:3] + return HttpResponse(json.dumps(data)) + +def zip_documents(docs, code): + files = [] + total = len(docs) + status = 0 + progress[code][0] = status + progress[code][1] = total + 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, i.user.groups.values_list('name', flat=True)[0]] + 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) + filename = i.user.username+"_"+i.document_type.name+".pdf" + files.append((filename, pdf)) + status += 1 + progress[code][0] = status + + mem_zip = BytesIO() + + with zipfile.ZipFile(mem_zip, mode="w",compression=zipfile.ZIP_DEFLATED) as zf: + for f in files: + zf.writestr(f[0], f[1]) + + mem_zip.seek(0) + progress[code][4] = FileResponse(mem_zip, as_attachment=True, filename="documents_" + datetime.now().strftime("%H_%M-%d_%m_%y") + ".zip") + progress[code][2] = True @user_passes_test(isStaff) def upload_doc(request): |