Ajout du frontend et branchement sur l'API axione #9
3 changed files with 51 additions and 29 deletions
|
@ -28,28 +28,38 @@ class AddressFinder:
|
||||||
self.dbPath = db_addresses_sqlite_path
|
self.dbPath = db_addresses_sqlite_path
|
||||||
print("DB addresses Path : " + self.dbPath)
|
print("DB addresses Path : " + self.dbPath)
|
||||||
|
|
||||||
def getCommunesFromNameOrZip(self, communeNameOrZip: str) -> list[Commune]:
|
def getCommunesFromNameOrZip(self, communeNameOrZip: str, limit: int = None) -> list[Commune]:
|
||||||
con = sqlite3.connect(self.dbPath)
|
con = sqlite3.connect(self.dbPath)
|
||||||
con.row_factory = sqlite3.Row
|
con.row_factory = sqlite3.Row
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
communes: list[Commune] = []
|
|
||||||
|
# Check if a search limit is specified, make sure it is an integer
|
||||||
|
select_limit = ""
|
||||||
|
if limit is not None:
|
||||||
|
try:
|
||||||
|
select_limit = f"LIMIT {int(limit)}"
|
||||||
|
except ValueError:
|
||||||
|
print("Error, limit arg not a valid int: ", limit)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# If no search parameter, select all
|
||||||
if communeNameOrZip is None:
|
if communeNameOrZip is None:
|
||||||
cur.execute(f"SELECT * from \"{DB_TABLE_INSEE_NAME}\"")
|
cur.execute(
|
||||||
|
f"SELECT * from \"{DB_TABLE_INSEE_NAME}\" {select_limit}")
|
||||||
else:
|
else:
|
||||||
communeSearch = communeNameOrZip
|
communeSearch = communeNameOrZip
|
||||||
zipSearch = communeNameOrZip
|
zipSearch = communeNameOrZip
|
||||||
searchOpertor = "OR"
|
searchOpertor = "OR"
|
||||||
|
|
||||||
regexCommuneAndZip = r"[0-9]{5} .+" # For example: '33000 BO'
|
# Allow search zip and commune at the same time, in the format "29530 PLO"
|
||||||
|
regexCommuneAndZip = r"[0-9]{5} .+"
|
||||||
if re.match(regexCommuneAndZip, communeNameOrZip):
|
if re.match(regexCommuneAndZip, communeNameOrZip):
|
||||||
splitSearch = communeNameOrZip.split(' ')
|
splitSearch = communeNameOrZip.split(' ')
|
||||||
zipSearch = splitSearch[0]
|
zipSearch = splitSearch[0]
|
||||||
communeSearch = ' '.join(splitSearch[1:])
|
communeSearch = ' '.join(splitSearch[1:])
|
||||||
searchOpertor = "AND"
|
searchOpertor = "AND"
|
||||||
cur.execute(
|
cur.execute(
|
||||||
f"SELECT * from \"{DB_TABLE_INSEE_NAME}\" WHERE {DB_COL_COMMUNE_NAME} LIKE \"%{communeSearch}%\" COLLATE nocase {searchOpertor} {DB_COL_COMMUNE_POSTE} LIKE \"{zipSearch}%\"")
|
f"SELECT * from \"{DB_TABLE_INSEE_NAME}\" WHERE {DB_COL_COMMUNE_NAME} LIKE \"%{communeSearch}%\" COLLATE nocase {searchOpertor} {DB_COL_COMMUNE_POSTE} LIKE \"{zipSearch}%\" {select_limit}")
|
||||||
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 []
|
||||||
|
@ -61,13 +71,13 @@ class AddressFinder:
|
||||||
codeInsee=row_obj[DB_COL_COMMUNE_INSEE],
|
codeInsee=row_obj[DB_COL_COMMUNE_INSEE],
|
||||||
nom=row_obj[DB_COL_COMMUNE_NAME],
|
nom=row_obj[DB_COL_COMMUNE_NAME],
|
||||||
codeZip=row_obj[DB_COL_COMMUNE_POSTE])
|
codeZip=row_obj[DB_COL_COMMUNE_POSTE])
|
||||||
# This way we avoid duplicates
|
# This way we avoid duplicates in DB
|
||||||
communesMap[commune["codeInsee"]] = commune
|
communesMap[commune["codeInsee"]] = commune
|
||||||
|
|
||||||
con.close()
|
con.close()
|
||||||
return list(communesMap.values())
|
return list(communesMap.values())
|
||||||
|
|
||||||
def getCommuneFantoirVoies(self, communeInseeCode: str, voieSearch: str = None) -> list[FantoirVoie]:
|
def getCommuneFantoirVoies(self, communeInseeCode: str, voieSearch: str = None, limit: int = None) -> list[FantoirVoie]:
|
||||||
|
|
||||||
# Extract data from DB
|
# Extract data from DB
|
||||||
con = sqlite3.connect(self.dbPath)
|
con = sqlite3.connect(self.dbPath)
|
||||||
|
@ -84,6 +94,13 @@ class AddressFinder:
|
||||||
|
|
||||||
# Get JSON payload
|
# Get JSON payload
|
||||||
|
|
||||||
|
# Check if a search limit is specified, make sure it is an integer
|
||||||
|
if limit is not None:
|
||||||
|
try:
|
||||||
|
limit = int(limit)
|
||||||
|
except ValueError:
|
||||||
|
print("Error, limit arg not a valid int: ", limit)
|
||||||
|
|
||||||
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:
|
||||||
|
@ -92,19 +109,28 @@ class AddressFinder:
|
||||||
data_dict = json.loads(data.get("value"))
|
data_dict = json.loads(data.get("value"))
|
||||||
# In extracted JSON data, the interesting payload is behind "value" key
|
# In extracted JSON data, the interesting payload is behind "value" key
|
||||||
fantoir_dict = data_dict.get("value")
|
fantoir_dict = data_dict.get("value")
|
||||||
|
|
||||||
|
# Apply search filter if any
|
||||||
if voieSearch is not None:
|
if voieSearch is not None:
|
||||||
|
# Can match multiple words, for example "avenue noe" matches "avenue de noes"
|
||||||
regexSearch = r".*"
|
regexSearch = r".*"
|
||||||
for expr in voieSearch.split(' '):
|
for expr in voieSearch.split(' '):
|
||||||
regexSearch += r"(?=" + expr + r").*"
|
regexSearch += r"(?=" + expr + r").*"
|
||||||
regexSearch += r".*"
|
regexSearch += r".*"
|
||||||
fantoir_voies_filtered = []
|
fantoir_voies_filtered = []
|
||||||
|
nb_match = 0
|
||||||
for voie in fantoir_dict:
|
for voie in fantoir_dict:
|
||||||
for libelle in voie['libelle']:
|
for libelle in voie['libelle']:
|
||||||
if re.search(regexSearch, libelle, re.IGNORECASE):
|
if re.search(regexSearch, libelle, re.IGNORECASE):
|
||||||
fantoir_voies_filtered.append(voie)
|
fantoir_voies_filtered.append(voie)
|
||||||
|
nb_match += 1
|
||||||
break
|
break
|
||||||
fantoir_dict = fantoir_voies_filtered
|
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))
|
||||||
|
|
|
@ -85,9 +85,9 @@
|
||||||
var voies=[]
|
var voies=[]
|
||||||
var voie=""
|
var voie=""
|
||||||
function fillCommunes(search='') {
|
function fillCommunes(search='') {
|
||||||
var api="addresses/communes";
|
var api="addresses/communes?limit=15";
|
||||||
if (search != '') {
|
if (search != '') {
|
||||||
api+="?s="+search;
|
api+="&s="+search;
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
|
@ -97,13 +97,10 @@
|
||||||
if (JSON.stringify(data) !== JSON.stringify(communes)){
|
if (JSON.stringify(data) !== JSON.stringify(communes)){
|
||||||
$("#communes").empty();
|
$("#communes").empty();
|
||||||
communes=data
|
communes=data
|
||||||
for (let i = 0; i < 20; i++) {
|
communes.forEach(commune => {
|
||||||
if (! communes[i]) {
|
$("#communes").append("<option codeInsee=" + commune.codeInsee + " value='" +
|
||||||
break;
|
commune.codeZip + ' ' + commune.nom + "'></option>");
|
||||||
}
|
});
|
||||||
$("#communes").append("<option codeInsee=" + communes[i].codeInsee + " value='" +
|
|
||||||
communes[i].codeZip + ' ' + communes[i].nom + "'></option>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (communes.length == 1) {
|
if (communes.length == 1) {
|
||||||
codeInsee=communes[0].codeInsee;
|
codeInsee=communes[0].codeInsee;
|
||||||
|
@ -119,9 +116,9 @@
|
||||||
|
|
||||||
var voies=[]
|
var voies=[]
|
||||||
function fillVoies(codeInsee,search='') {
|
function fillVoies(codeInsee,search='') {
|
||||||
var api="addresses/fantoirvoies/" + codeInsee;
|
var api="addresses/fantoirvoies/" + codeInsee + '?limit=15';
|
||||||
if (search != '') {
|
if (search != '') {
|
||||||
api+="?s="+search;
|
api+="&s="+search;
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
|
@ -131,13 +128,10 @@
|
||||||
if (JSON.stringify(data) !== JSON.stringify(voies)){
|
if (JSON.stringify(data) !== JSON.stringify(voies)){
|
||||||
$("#voies").empty();
|
$("#voies").empty();
|
||||||
voies=data
|
voies=data
|
||||||
for (let i = 0; i < 20; i++) {
|
voies.forEach(voie => {
|
||||||
if (! voies[i]) {
|
$("#voies").append("<option id=" + voie.id + " value='" +
|
||||||
break;
|
voie.libelle[0] + "'></option>");
|
||||||
}
|
});
|
||||||
$("#voies").append("<option id=" + voies[i].id + " value='" +
|
|
||||||
voies[i].libelle[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]
|
||||||
|
|
|
@ -33,7 +33,8 @@ def get_form():
|
||||||
@app.route("/addresses/communes", methods=['GET'])
|
@app.route("/addresses/communes", methods=['GET'])
|
||||||
def get_communes():
|
def get_communes():
|
||||||
to_search=request.args.get('s')
|
to_search=request.args.get('s')
|
||||||
communes=addressFinder.getCommunesFromNameOrZip(to_search)
|
limit=request.args.get('limit')
|
||||||
|
communes=addressFinder.getCommunesFromNameOrZip(to_search,limit)
|
||||||
response = app.response_class(
|
response = app.response_class(
|
||||||
response=json.dumps(communes),
|
response=json.dumps(communes),
|
||||||
mimetype='application/json'
|
mimetype='application/json'
|
||||||
|
@ -43,7 +44,8 @@ def get_communes():
|
||||||
@app.route("/addresses/fantoirvoies/<codeInsee>", methods=['GET'])
|
@app.route("/addresses/fantoirvoies/<codeInsee>", methods=['GET'])
|
||||||
def get_fantoir_voies(codeInsee):
|
def get_fantoir_voies(codeInsee):
|
||||||
to_search=request.args.get('s')
|
to_search=request.args.get('s')
|
||||||
fantoirVoies=addressFinder.getCommuneFantoirVoies(codeInsee,to_search)
|
limit=request.args.get('limit')
|
||||||
|
fantoirVoies=addressFinder.getCommuneFantoirVoies(codeInsee,to_search,limit)
|
||||||
response = app.response_class(
|
response = app.response_class(
|
||||||
response=json.dumps(fantoirVoies),
|
response=json.dumps(fantoirVoies),
|
||||||
mimetype='application/json'
|
mimetype='application/json'
|
||||||
|
|
Loading…
Reference in a new issue