adresses API: add limit param

This commit is contained in:
Johan Le Baut 2022-01-28 15:42:08 +01:00
parent 768418258e
commit 46aeaf7da4
3 changed files with 51 additions and 29 deletions

View file

@ -28,28 +28,38 @@ class AddressFinder:
self.dbPath = db_addresses_sqlite_path
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.row_factory = sqlite3.Row
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:
# If no search parameter, select all
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:
communeSearch = communeNameOrZip
zipSearch = communeNameOrZip
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):
splitSearch = communeNameOrZip.split(' ')
zipSearch = splitSearch[0]
communeSearch = ' '.join(splitSearch[1:])
searchOpertor = "AND"
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:
print("Error querying DB : {0}".format(err), file=sys.stderr)
return []
@ -61,13 +71,13 @@ class AddressFinder:
codeInsee=row_obj[DB_COL_COMMUNE_INSEE],
nom=row_obj[DB_COL_COMMUNE_NAME],
codeZip=row_obj[DB_COL_COMMUNE_POSTE])
# This way we avoid duplicates
# This way we avoid duplicates in DB
communesMap[commune["codeInsee"]] = commune
con.close()
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
con = sqlite3.connect(self.dbPath)
@ -84,6 +94,13 @@ class AddressFinder:
# 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 = []
# Check if data where found
if data_raw is not None:
@ -92,19 +109,28 @@ class AddressFinder:
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:
print("Did not found any data matching Insee code " +
str(communeInseeCode))

View file

@ -85,9 +85,9 @@
var voies=[]
var voie=""
function fillCommunes(search='') {
var api="addresses/communes";
var api="addresses/communes?limit=15";
if (search != '') {
api+="?s="+search;
api+="&s="+search;
}
$.ajax({
type: 'GET',
@ -97,13 +97,10 @@
if (JSON.stringify(data) !== JSON.stringify(communes)){
$("#communes").empty();
communes=data
for (let i = 0; i < 20; i++) {
if (! communes[i]) {
break;
}
$("#communes").append("<option codeInsee=" + communes[i].codeInsee + " value='" +
communes[i].codeZip + ' ' + communes[i].nom + "'></option>");
}
communes.forEach(commune => {
$("#communes").append("<option codeInsee=" + commune.codeInsee + " value='" +
commune.codeZip + ' ' + commune.nom + "'></option>");
});
}
if (communes.length == 1) {
codeInsee=communes[0].codeInsee;
@ -119,9 +116,9 @@
var voies=[]
function fillVoies(codeInsee,search='') {
var api="addresses/fantoirvoies/" + codeInsee;
var api="addresses/fantoirvoies/" + codeInsee + '?limit=15';
if (search != '') {
api+="?s="+search;
api+="&s="+search;
}
$.ajax({
type: 'GET',
@ -131,13 +128,10 @@
if (JSON.stringify(data) !== JSON.stringify(voies)){
$("#voies").empty();
voies=data
for (let i = 0; i < 20; i++) {
if (! voies[i]) {
break;
}
$("#voies").append("<option id=" + voies[i].id + " value='" +
voies[i].libelle[0] + "'></option>");
}
voies.forEach(voie => {
$("#voies").append("<option id=" + voie.id + " value='" +
voie.libelle[0] + "'></option>");
});
if (voies.length == 1) {
$('#btnTestAdresse').collapse('show');
voie=voies[0].libelle[0]

View file

@ -33,7 +33,8 @@ def get_form():
@app.route("/addresses/communes", methods=['GET'])
def get_communes():
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=json.dumps(communes),
mimetype='application/json'
@ -43,7 +44,8 @@ def get_communes():
@app.route("/addresses/fantoirvoies/<codeInsee>", methods=['GET'])
def get_fantoir_voies(codeInsee):
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=json.dumps(fantoirVoies),
mimetype='application/json'