This repository has been archived by the owner on Feb 4, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
views.py
149 lines (122 loc) · 5.4 KB
/
views.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
# Create your views here.
from django.http import HttpResponse
from django.shortcuts import render_to_response, render
from django import forms
import tempfile
import os
import json
import codecs
import pyxform
from pyxform import xls2json
from pyxform.utils import sheet_to_csv
SERVER_TMP_DIR = '/tmp/tmp_www-data'
class UploadFileForm(forms.Form):
file = forms.FileField()
def handle_uploaded_file(f, temp_dir):
xls_path = os.path.join(temp_dir, f.name)
destination = open(xls_path, 'wb+')
for chunk in f.chunks():
destination.write(chunk)
destination.close()
return xls_path
def json_workbook(request):
error = None
warningsList = []
if not (os.access(SERVER_TMP_DIR, os.F_OK)):
os.mkdir(SERVER_TMP_DIR)
#Make a randomly generated directory to prevent name collisions
temp_dir = tempfile.mkdtemp(dir=SERVER_TMP_DIR)
form_name = request.POST.get('name', 'form')
output_filename = form_name + '.xml'
out_path = os.path.join(temp_dir, output_filename)
if os.access(out_path, os.F_OK):
os.remove(out_path)
try:
json_survey = xls2json.workbook_to_json(json.loads(request.POST['workbookJson']), form_name=form_name,
warnings=warningsList)
survey = pyxform.create_survey_element_from_dict(json_survey)
survey.print_xform_to_file(out_path, warnings=warningsList)
except Exception as e:
error = str(e)
return HttpResponse(json.dumps({
'dir': os.path.split(temp_dir)[-1],
'name': output_filename,
'error': error,
'warnings': warningsList,
}, indent=4), mimetype="application/json")
def has_external_choices(json_struct):
"""
Returns true if a select one external prompt is used in the survey.
"""
if isinstance(json_struct, dict):
for k, v in json_struct.items():
if k == u"type" and v.startswith(u"select one external"):
return True
elif has_external_choices(v):
return True
elif isinstance(json_struct, list):
for v in json_struct:
if has_external_choices(v):
return True
return False
def index(request):
if request.method == 'POST': # If the form has been submitted...
form = UploadFileForm(request.POST, request.FILES) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
error = None
warnings = None
filename, ext = os.path.splitext(request.FILES['file'].name)
if not (os.access(SERVER_TMP_DIR, os.F_OK)):
os.mkdir(SERVER_TMP_DIR)
#Make a randomly generated directory to prevent name collisions
temp_dir = tempfile.mkdtemp(dir=SERVER_TMP_DIR)
xml_path = os.path.join(temp_dir, filename + '.xml')
itemsets_url = None
relpath = os.path.relpath(xml_path, SERVER_TMP_DIR)
#Init the output xml file.
fo = open(xml_path, "wb+")
fo.close()
try:
#TODO: use the file object directly
xls_path = handle_uploaded_file(request.FILES['file'], temp_dir)
warnings = []
json_survey = xls2json.parse_file_to_json(xls_path, warnings=warnings)
survey = pyxform.create_survey_element_from_dict(json_survey)
survey.print_xform_to_file(xml_path, warnings=warnings)
if has_external_choices(json_survey):
# Create a csv for the external choices
itemsets_csv = os.path.join(os.path.split(xls_path)[0],
"itemsets.csv")
relpath_itemsets_csv = os.path.relpath(itemsets_csv, SERVER_TMP_DIR)
choices_exported = sheet_to_csv(xls_path, itemsets_csv,
"external_choices")
if not choices_exported:
warnings += ["Could not export itemsets.csv, "
"perhaps the external choices sheet is missing."]
else:
itemsets_url = request.build_absolute_uri('./downloads/' + relpath_itemsets_csv)
except Exception as e:
error = 'Error: ' + str(e)
return render_to_response('upload.html', {
'form': UploadFileForm(),
'xml_path': request.build_absolute_uri('./downloads/' + relpath),
'xml_url': request.build_absolute_uri('./downloads/' + relpath),
'itemsets_url': itemsets_url,
'success': not error,
'error': error,
'warnings': warnings,
'result': True,
})
else:
form = UploadFileForm() # An unbound form
return render(request, 'upload.html', context={
'form': form,
})
def serve_file(request, path):
fo = codecs.open(os.path.join(SERVER_TMP_DIR, path), mode='r', encoding='utf-8')
data = fo.read()
fo.close()
response = HttpResponse(content_type='application/octet-stream')
#response['Content-Disposition'] = 'attachment; filename=somefilename.xml'
response.write(data)
return response