Ajout du frontend et branchement sur l'API axione #9
4 changed files with 59 additions and 50 deletions
|
@ -45,3 +45,9 @@ curl -v http://127.0.0.1:5000/addresses/communes?s=29530
|
||||||
# Chercher les voies d'une commune via son code insee
|
# Chercher les voies d'une commune via son code insee
|
||||||
curl -v http://127.0.0.1:5000/addresses/fantoirvoies/29036
|
curl -v http://127.0.0.1:5000/addresses/fantoirvoies/29036
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Jeux de données
|
||||||
|
|
||||||
|
#### Insee
|
||||||
|
|
||||||
|
Importez ce CSV https://www.data.gouv.fr/fr/datasets/base-officielle-des-codes-postaux/ dans la base de données
|
||||||
|
|
|
@ -85,15 +85,13 @@ class AddressFinder:
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
try:
|
try:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
f"SELECT value from \"{DB_TABLE_FANTOIR_NAME}\" WHERE {DB_COL_FANTOIR_INSEE}=\"{DB_FANTOIR_INSEE_KEY_SUFFIX}{communeInseeCode}\"")
|
f"SELECT trim(libelle), rivoli_with_key from fantoir WHERE full_insee=\"{communeInseeCode}\" AND libelle like \"%{voieSearch}%\"")
|
||||||
except sqlite3.OperationalError as err:
|
except sqlite3.OperationalError as err:
|
||||||
print("Error querying DB : {0}".format(err), file=sys.stderr)
|
print("Error querying DB : {0}".format(err), file=sys.stderr)
|
||||||
return []
|
return []
|
||||||
data_raw = cur.fetchone()
|
data_raw = cur.fetchall()
|
||||||
con.close()
|
con.close()
|
||||||
|
|
||||||
# Get JSON payload
|
|
||||||
|
|
||||||
# Check if a search limit is specified, make sure it is an integer
|
# Check if a search limit is specified, make sure it is an integer
|
||||||
if limit is not None:
|
if limit is not None:
|
||||||
try:
|
try:
|
||||||
|
@ -104,33 +102,7 @@ class AddressFinder:
|
||||||
fantoir_dict = []
|
fantoir_dict = []
|
||||||
# Check if data where found
|
# Check if data where found
|
||||||
if data_raw is not None:
|
if data_raw is not None:
|
||||||
data = dict(data_raw)
|
fantoir_dict = dict(data_raw)
|
||||||
# Extract the data behind "value" which is a JSON structure
|
|
||||||
data_dict = json.loads(data.get("value"))
|
|
||||||
# In extracted JSON data, the interesting payload is behind "value" key
|
|
||||||
fantoir_dict = data_dict.get("value")
|
|
||||||
|
|
||||||
# Apply search filter if any
|
|
||||||
if voieSearch is not None:
|
|
||||||
# Can match multiple words, for example "avenue noe" matches "avenue de noes"
|
|
||||||
regexSearch = r".*"
|
|
||||||
for expr in voieSearch.split(' '):
|
|
||||||
regexSearch += r"(?=" + expr + r").*"
|
|
||||||
regexSearch += r".*"
|
|
||||||
fantoir_voies_filtered = []
|
|
||||||
nb_match = 0
|
|
||||||
for voie in fantoir_dict:
|
|
||||||
for libelle in voie['libelle']:
|
|
||||||
if re.search(regexSearch, libelle, re.IGNORECASE):
|
|
||||||
fantoir_voies_filtered.append(voie)
|
|
||||||
nb_match += 1
|
|
||||||
break
|
|
||||||
if limit is not None and nb_match >= limit:
|
|
||||||
break
|
|
||||||
fantoir_dict = fantoir_voies_filtered
|
|
||||||
else:
|
|
||||||
# Apply search limit if any
|
|
||||||
fantoir_dict = fantoir_dict[:limit]
|
|
||||||
else:
|
else:
|
||||||
print("Did not found any data matching Insee code " +
|
print("Did not found any data matching Insee code " +
|
||||||
str(communeInseeCode))
|
str(communeInseeCode))
|
||||||
|
|
29
scripts/import-laposte-insee.sh
Executable file
29
scripts/import-laposte-insee.sh
Executable file
|
@ -0,0 +1,29 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eau -o pipefail
|
||||||
|
|
||||||
|
if [ "$#" -ne 2 ]; then
|
||||||
|
echo "Usage: import-laposte-insee.sh path-to-laposte-insee-CSV fantoir-sqlite-db-path"
|
||||||
|
echo ""
|
||||||
|
echo "ERROR: Missing laposte CSV."
|
||||||
|
echo "You can download it at https://www.data.gouv.fr/fr/datasets/base-officielle-des-codes-postaux/"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmpDir=$(mktemp -d)
|
||||||
|
clean_tmp () {
|
||||||
|
rm -r "${tmpDir}"
|
||||||
|
}
|
||||||
|
trap clean_tmp EXIT
|
||||||
|
tmpSql="${tmpDir}"/import-laposte-hexasmal.sql
|
||||||
|
|
||||||
|
echo "Importing laposte/insee hexasmal data into the fantoir db."
|
||||||
|
|
||||||
|
cat >"${tmpSql}" <<EOF
|
||||||
|
.separator ";"
|
||||||
|
.import $1 insee
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sqlite3 "${2}" < "${tmpSql}"
|
||||||
|
|
||||||
|
|
||||||
|
echo "Data imported"
|
|
@ -18,18 +18,18 @@
|
||||||
<body>
|
<body>
|
||||||
<h1 class="text-center" id="aquilenet-title">AQUILENET</h1>
|
<h1 class="text-center" id="aquilenet-title">AQUILENET</h1>
|
||||||
<div id="mainContainer" class="container">
|
<div id="mainContainer" class="container">
|
||||||
|
|
||||||
<div class="row d-flex justify-content-between align-items-center" data-parent="#mainContainer">
|
<div class="row d-flex justify-content-between align-items-center" data-parent="#mainContainer">
|
||||||
|
|
||||||
<div class="col-12 text-intro">
|
<div class="col-12 text-intro">
|
||||||
<div id="methodPto" class="collapse show testMethods">
|
<div id="methodPto" class="collapse show testMethods">
|
||||||
|
|
||||||
<h2 class="text-center form-title">Test d'éligibilité par PTO</h1>
|
<h2 class="text-center form-title">Test d'éligibilité par PTO</h1>
|
||||||
<form method="post" action="/test/pto">
|
<form method="post" action="/test/pto">
|
||||||
<div class="form-group" id="ptoForm">
|
<div class="form-group" id="ptoForm">
|
||||||
<label class="form-label" for="pto-number">Numéro PTO</label>
|
<label class="form-label" for="pto-number">Numéro PTO</label>
|
||||||
<input required type="text" class="form-control" name="pto" id="pto-number" aria-describedby="ptoHelp" placeholder="OOOO-XXXX-XXXX" oninvalid="this.setCustomValidity('Veuillez renseigner le PTO')" oninput="setCustomValidity('')">
|
<input required type="text" class="form-control" name="pto" id="pto-number" aria-describedby="ptoHelp" placeholder="OOOO-XXXX-XXXX" oninvalid="this.setCustomValidity('Veuillez renseigner le PTO')" oninput="setCustomValidity('')">
|
||||||
|
|
||||||
<small id="ptoHelp" class="form-text btn btn-link" data-toggle="collapse" data-target="#ptoInfo" aria-expanded="true" aria-controls="ptoInfo">Où trouver mon numéro de PTO ?</small>
|
<small id="ptoHelp" class="form-text btn btn-link" data-toggle="collapse" data-target="#ptoInfo" aria-expanded="true" aria-controls="ptoInfo">Où trouver mon numéro de PTO ?</small>
|
||||||
<div id="ptoInfo" class="collapse" aria-labelledby="ptoForm" data-parent="#ptoForm">
|
<div id="ptoInfo" class="collapse" aria-labelledby="ptoForm" data-parent="#ptoForm">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
@ -39,10 +39,10 @@
|
||||||
<img src="{{url_for('static', filename='find_pto.jpg')}}" class="img-fluid" alt="Responsive image">
|
<img src="{{url_for('static', filename='find_pto.jpg')}}" class="img-fluid" alt="Responsive image">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-sable">Tester le PTO</button>
|
<button type="submit" class="btn btn-sable">Tester le PTO</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<button id="buttonNoPto" type="button" data-toggle="collapse" data-target=".testMethods" class="btn btn-link" aria-expanded="false" aria-controls="methodPto methodAddress">Je n'ai pas/ne trouve pas le PTO, tester autrement</button>
|
<button id="buttonNoPto" type="button" data-toggle="collapse" data-target=".testMethods" class="btn btn-link" aria-expanded="false" aria-controls="methodPto methodAddress">Je n'ai pas/ne trouve pas le PTO, tester autrement</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
<label class="form-label" for="communeInput">Commune</label>
|
<label class="form-label" for="communeInput">Commune</label>
|
||||||
<input type="text" list="communes" name="commune" class="form-control" id="communeInput" ondblclick="this.focus();this.select()" aria-describedby="communeHelp" placeholder="Nom de la commune ou code postal">
|
<input type="text" list="communes" name="commune" class="form-control" id="communeInput" ondblclick="this.focus();this.select()" aria-describedby="communeHelp" placeholder="Nom de la commune ou code postal">
|
||||||
<datalist id="communes">
|
<datalist id="communes">
|
||||||
</datalist>
|
</datalist>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row collapse" id="voieForm">
|
<div class="form-row collapse" id="voieForm">
|
||||||
<div class="col-sm-3 my-1">
|
<div class="col-sm-3 my-1">
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
<label class="form-label" for="voieInput">Nom de voie</label>
|
<label class="form-label" for="voieInput">Nom de voie</label>
|
||||||
<input type="text" name="voie" list="voies" class="form-control" id="voieInput" aria-describedby="voieHelp" placeholder="Nom de voie">
|
<input type="text" name="voie" list="voies" class="form-control" id="voieInput" aria-describedby="voieHelp" placeholder="Nom de voie">
|
||||||
<datalist id="voies">
|
<datalist id="voies">
|
||||||
</datalist>
|
</datalist>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
@ -98,8 +98,8 @@
|
||||||
$("#communes").empty();
|
$("#communes").empty();
|
||||||
communes=data
|
communes=data
|
||||||
communes.forEach(commune => {
|
communes.forEach(commune => {
|
||||||
$("#communes").append("<option codeInsee=" + commune.codeInsee + " value='" +
|
$("#communes").append("<option codeInsee=" + commune.codeInsee + " value='" +
|
||||||
commune.codeZip + ' ' + commune.nom + "'></option>");
|
commune.codeZip + ' ' + commune.nom + "'></option>");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (communes.length == 1) {
|
if (communes.length == 1) {
|
||||||
|
@ -127,14 +127,16 @@
|
||||||
success: function (data, status, xhr) {
|
success: function (data, status, xhr) {
|
||||||
if (JSON.stringify(data) !== JSON.stringify(voies)){
|
if (JSON.stringify(data) !== JSON.stringify(voies)){
|
||||||
$("#voies").empty();
|
$("#voies").empty();
|
||||||
voies=data
|
voies=Object.entries(data);
|
||||||
voies.forEach(voie => {
|
let voie;
|
||||||
$("#voies").append("<option id=" + voie.id + " value='" +
|
for (i in voies) {
|
||||||
voie.libelle[0] + "'></option>");
|
voie = voies[i]
|
||||||
});
|
$("#voies").append("<option id=" + voie[1] + " value='" +
|
||||||
|
voie[0] + "'></option>");
|
||||||
|
}
|
||||||
if (voies.length == 1) {
|
if (voies.length == 1) {
|
||||||
$('#btnTestAdresse').collapse('show');
|
$('#btnTestAdresse').collapse('show');
|
||||||
voie=voies[0].libelle[0]
|
voie=voies[0].libelle[0]
|
||||||
} else {
|
} else {
|
||||||
$('#btnTestAdresse').collapse('hide');
|
$('#btnTestAdresse').collapse('hide');
|
||||||
}
|
}
|
||||||
|
@ -150,11 +152,11 @@
|
||||||
$('#voieInput').trigger('input')
|
$('#voieInput').trigger('input')
|
||||||
$('#voieInput').trigger('keyup')
|
$('#voieInput').trigger('keyup')
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#communeInput').on('keyup', function () {
|
$('#communeInput').on('keyup', function () {
|
||||||
fillCommunes($(this).val());
|
fillCommunes($(this).val());
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#communeInput').on('input', function() {
|
$('#communeInput').on('input', function() {
|
||||||
if ($(this).val() === '') {
|
if ($(this).val() === '') {
|
||||||
$('#voieForm').collapse('hide');
|
$('#voieForm').collapse('hide');
|
||||||
|
@ -168,7 +170,7 @@
|
||||||
$('#btnTestAdresse').collapse('hide');
|
$('#btnTestAdresse').collapse('hide');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Reference in a new issue