...
 
Commits (2)
from django import forms
class ImportCsvForm(forms.Form):
fname = forms.FileField(label="Fichier à importer")
......@@ -9,9 +9,19 @@
<script src="{% static 'jquery-ui/jquery-ui.js' %}" type="text/javascript"></script>
<script type="text/javascript" src="{% static 'portrait.js' %}"></script>
<link rel="stylesheet" href="{% static 'portrait.css' %}" type="text/css"/>
<link rel="stylesheet" type="text/css" href="{% static '/admin/css/base.css' %}" />
</head>
<body>
<input type="hidden" id="csrf" value="{{csrf_token}}"/>
<form method="post" action="" enctype="multipart/form-data">
<fieldset>
<legend>Fichier de type CSV</legend>
{% csrf_token %}
<table>
{{form.as_table}}
<tr><td colspan="2" style="text-align: center;"><input type="submit" value="Importer"/></td></tr>
</table>
</fieldset>
</form>
<h1>Importation d'élèves</h1>
<dl>
<dt>Fichier</dt>
......
......@@ -58,6 +58,12 @@
<video id="webcam" autoplay ></video>
</div>
</div>
<div id="footer">
<h3>Liens :</h3>
<ul>
<li><a href="/importeCSV">Importation depuis un fichier CSV</a></li>
</ul>
</div>
<div id="dialog"></div>
</body>
</html>
......
......@@ -3,8 +3,9 @@ from django.http import JsonResponse, HttpResponse
from django.utils import timezone
from .models import Person
from .autoretouche import jpgPrefix, FaceImage
from .forms import ImportCsvForm
from photodb.settings import BASE_DIR
import re, os, base64, uuid, csv, json
import re, os, base64, uuid, csv, json, io
def json_response(F):
......@@ -173,43 +174,49 @@ def cherchePrenom(request):
def find_encoding(f, encodings):
"""
finds the encoding of a text file
@param f file path
@param f a bytesIO object
@param encodings a list of encodings to try
@return the first encoding which allowed one to read the file, or None
"""
f.seek(0)
contents=f.read()
f.seek(0)
for e in encodings:
try:
with open(f,encoding=e) as infile:
s=infile.read()
contents.decode(e)
return e
except:
pass
return None
def getReader(csvfile, fields):
def getReader(csvio, fields, encoding):
"""
makes a DictReader from the file f, with the given encoding.
This Dictrader must have one field with name matched by secondNamePattern
and another one with name matched by firstNamePattern
@param csvfile an open string stream
@param csvio a BytesIO stream
@param fields a dictionary:
Person's field => (compiled re pattern, found field name)
@param encoding an encoding able to decode csvio
@return a Dictreader, and the updated dictionary
"""
reader=None
csvio.seek(0)
content=csvio.read().decode(encoding)
csvio=io.StringIO(content)
for delimiter in (";", ",", "\t",):
csvfile.seek(0)
reader = csv.DictReader(csvfile, delimiter=delimiter)
nbfound=0
for f in fields:
found=[fn for fn in reader.fieldnames if fields[f][0].match(fn)]
if found:
fields[f][1]=found[0]
nbfound+=1
else:
fields[f][1]=""
if nbfound>=2: # fields were made visible
return reader, fields
csvio.seek(0)
reader = csv.DictReader(csvio, delimiter=delimiter)
nbfound=0
for f in fields:
found=[fn for fn in reader.fieldnames if fields[f][0].match(fn)]
if found:
fields[f][1]=found[0]
nbfound+=1
else:
fields[f][1]=""
if nbfound>=2: # fields were made visible
return reader, fields
return reader, fields
def addToDb(row, fields):
......@@ -248,6 +255,15 @@ def importeCSV(request):
the first line may contain field names like:
"#?nom", "pr[eé]nom", "niveau", "classe"
"""
form=ImportCsvForm(request)
if 'fname' not in request.FILES or request.FILES['fname'].content_type != "text/csv":
return render(request, "pose/importCSV.html", {
"fname": "Fichier non encore choisi",
"written": 0,
"form": form,
})
# fname is defined
bio=request.FILES['fname'].file
encodingList=[
"utf-8",
"latin1",
......@@ -262,16 +278,13 @@ def importeCSV(request):
"className": [re.compile(r"^classe$", re.I), ""],
}
infile=os.path.join(BASE_DIR, "test.csv")
encoding=find_encoding(infile, encodingList)
encoding=find_encoding(bio, encodingList)
written=0
with open(infile, encoding=encoding) as csvfile:
reader, fields = getReader(csvfile, fields)
for r in reader:
written += addToDb(r, fields)
reader, fields = getReader(bio, fields, encoding)
for r in reader:
written += addToDb(r, fields)
return render(request, "pose/importCSV.html", {
"fname": infile,
"fname": request.FILES['fname'].name,
"written": written,
"form": form,
})