aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Lepori <alepori@student.ethz.ch>2020-08-30 19:44:26 +0200
committerAndrea Lepori <alepori@student.ethz.ch>2020-08-30 19:44:26 +0200
commit52f6b4e6a565835d54f7a736f7b90a7e1308ab7b (patch)
tree68b8c3df227442d5e6d46b836700a0fe4be36c6e
parentmore reliable generation progress (diff)
downloadscout-subs-52f6b4e6a565835d54f7a736f7b90a7e1308ab7b.tar.gz
scout-subs-52f6b4e6a565835d54f7a736f7b90a7e1308ab7b.zip
thread safe download multiple docs
-rw-r--r--server/templates/server/doc_list.html5
-rw-r--r--server/views.py42
2 files changed, 34 insertions, 13 deletions
diff --git a/server/templates/server/doc_list.html b/server/templates/server/doc_list.html
index 2159130..2bdc6c5 100644
--- a/server/templates/server/doc_list.html
+++ b/server/templates/server/doc_list.html
@@ -551,10 +551,9 @@ function update() {
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>";
+ 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><br>Clicca lo sfondo per chiudere la finestra";
document.getElementById('downloadLink').click();
-
} else {
bar.style.width = "100%";
box.innerHTML = "Impacchettamento documenti...";
diff --git a/server/views.py b/server/views.py
index c585d8b..b7462bb 100644
--- a/server/views.py
+++ b/server/views.py
@@ -25,6 +25,7 @@ import threading
import random
progress = {}
+lock = threading.Lock()
# custom staff check function for non primary group staff members
def isStaff(user):
@@ -788,30 +789,47 @@ def doclist(request):
'settings': settings,
}
+ # check if download multiple documents
if request.method == "POST":
if request.POST["action"] == "download" and len(selected) > 0:
+ # generate job id
code = request.user.username + "_" + str(random.randint(100, 999))
- progress[code] = [0, len(selected), False, request.user, None]
+ while code in progress.keys():
+ code = request.user.username + "_" + str(random.randint(100, 999))
+
+ # create job status object
+ with lock:
+ progress[code] = [0, len(selected), False, request.user, None]
+ # run job
threading.Thread(target=zip_documents, args=(selected, code)).start()
+ # pass job id
context["task_id"] = code
return render(request, 'server/doc_list.html', context)
def get_progress(request):
+ # check if asked for a job
if 'job' in request.GET:
job_id = request.GET['job']
else:
return HttpResponse(json.dumps({"error": True}))
+ # check if job is valid
if not job_id in progress.keys():
return HttpResponse(json.dumps({"error": "Lavoro non esistente. Provare a richiedere di nuovo il lavoro."}))
+ # if user wants to download result
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]
+ with lock:
+ # if user is authorized and job is completed
+ if request.GET['download'] == "true" and progress[job_id][3] == request.user:
+ data = progress[job_id][4]
+ del progress[job_id]
+ return data
+
+ # otherwise return status
+ with lock:
+ data = progress[job_id][:3]
return HttpResponse(json.dumps(data))
def zip_documents(docs, code):
@@ -847,18 +865,22 @@ def zip_documents(docs, code):
# render pdf using wkhtmltopdf
pdf = pdfkit.from_string(html, False)
filename = i.user.username+"_"+i.document_type.name+".pdf"
+ # append file
files.append((filename, pdf))
- progress[code][0] += 1
+ with lock:
+ progress[code][0] += 1
+ # zip documents
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
+ # save result
+ with lock:
+ 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):