0001-base_adresse-use-new-ban-data-38204.patch
passerelle/apps/base_adresse/models.py | ||
---|---|---|
1 |
import bz2 |
|
2 | 1 |
import datetime |
2 |
import gzip |
|
3 | 3 | |
4 | 4 |
from jsonfield import JSONField |
5 | 5 |
from requests import RequestException |
... | ... | |
10 | 10 |
from django.utils.translation import ugettext_lazy as _ |
11 | 11 |
from django.utils import timezone |
12 | 12 |
from django.utils import six |
13 |
from django.utils.six import StringIO |
|
13 | 14 |
from django.utils.six.moves.urllib import parse as urlparse |
14 | 15 | |
15 | 16 |
from passerelle.base.models import BaseResource |
... | ... | |
354 | 355 |
departments.add(zipcode[:2]) |
355 | 356 | |
356 | 357 |
for department in departments: |
357 |
ban_file = self.requests.get(
|
|
358 |
'http://bano.openstreetmap.fr/BAN_odbl/BAN_odbl_{}-json.bz2'.format(department))
|
|
359 |
if ban_file.status_code != 200:
|
|
358 |
ban_gz = self.requests.get(
|
|
359 |
'https://adresse.data.gouv.fr/data/ban/adresses/latest/addok/adresses-addok-{}.ndjson.gz'.format(department))
|
|
360 |
if ban_gz.status_code != 200:
|
|
360 | 361 |
continue |
361 | 362 | |
363 |
if six.PY3: |
|
364 |
ban_file = StringIO(gzip.decompress(ban_gz.content).decode('utf-8')) |
|
365 |
else: |
|
366 |
ban_file = gzip.GzipFile(fileobj=StringIO(ban_gz.content)) |
|
362 | 367 |
line = _not_found = object() |
363 |
for line in bz2.decompress(ban_file.content).splitlines():
|
|
368 |
for line in ban_file:
|
|
364 | 369 |
street_info = json_loads(line) |
365 | 370 |
if street_info['type'] == 'street' and street_info['postcode'].startswith(zipcodes): |
366 | 371 |
if type(street_info['citycode']) is list: |
367 | 372 |
street_info['citycode'] = six.text_type(street_info['citycode'][0]) |
368 | 373 |
if type(street_info['name']) is list: |
369 | 374 |
street_info['name'] = six.text_type(street_info['name'][0]) |
370 |
street = StreetModel.objects.get_or_create(citycode=street_info['citycode'],
|
|
371 |
name=street_info['name'][:150])
|
|
372 |
street[0].city = street_info['city']
|
|
373 |
street[0].name = street_info['name'][:150]
|
|
374 |
street[0].zipcode = street_info['postcode']
|
|
375 |
street[0].type = street_info['type']
|
|
376 |
street[0].citycode = street_info['citycode']
|
|
377 |
street[0].save()
|
|
375 |
StreetModel.objects.update_or_create(
|
|
376 |
citycode=street_info['citycode'],
|
|
377 |
name=street_info['name'][:150],
|
|
378 |
defaults={
|
|
379 |
'city': street_info['city'],
|
|
380 |
'zipcode': street_info['postcode'],
|
|
381 |
'type': street_info['type'],
|
|
382 |
})
|
|
378 | 383 |
if line is _not_found: |
379 | 384 |
raise Exception('bano file is empty') |
380 | 385 |
tests/test_base_adresse.py | ||
---|---|---|
348 | 348 |
assert resp.json['err'] == 0 |
349 | 349 |
assert len(resp.json['data']) == 0 |
350 | 350 | |
351 | ||
351 | 352 |
@pytest.mark.usefixtures('mock_update_api_geo') |
352 | 353 |
@mock.patch('passerelle.utils.Request.get') |
353 | 354 |
def test_base_adresse_command_update(mocked_get, db, base_adresse): |
354 |
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.bz2') |
|
355 |
mocked_get.return_value = utils.FakedResponse(content=open(filepath, 'rb').read(), status_code=200) |
|
355 |
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz') |
|
356 |
with open(filepath, 'rb') as ban_file: |
|
357 |
mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200) |
|
356 | 358 |
call_command('cron', 'daily') |
357 |
mocked_get.assert_called_once_with('http://bano.openstreetmap.fr/BAN_odbl/BAN_odbl_73-json.bz2')
|
|
359 |
mocked_get.assert_called_once_with('https://adresse.data.gouv.fr/data/ban/adresses/latest/addok/adresses-addok-73.ndjson.gz')
|
|
358 | 360 |
streets = StreetModel.objects.all() |
359 | 361 |
assert len(streets) == 3 |
360 | 362 |
street = StreetModel.objects.order_by('id').first() |
... | ... | |
372 | 374 |
@mock.patch('passerelle.utils.Request.get') |
373 | 375 |
def test_base_adresse_command_hourly_update(mocked_get, db, base_adresse): |
374 | 376 |
base_adresse.update_api_geo_data = lambda: None |
375 |
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.bz2') |
|
376 |
mocked_get.return_value = utils.FakedResponse(content=open(filepath, 'rb').read(), status_code=200) |
|
377 |
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz') |
|
378 |
with open(filepath, 'rb') as ban_file: |
|
379 |
mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200) |
|
377 | 380 |
# check the first hourly job downloads streets |
378 | 381 |
call_command('cron', 'hourly') |
379 |
mocked_get.assert_called_once_with('http://bano.openstreetmap.fr/BAN_odbl/BAN_odbl_73-json.bz2')
|
|
382 |
mocked_get.assert_called_once_with('https://adresse.data.gouv.fr/data/ban/adresses/latest/addok/adresses-addok-73.ndjson.gz')
|
|
380 | 383 |
assert StreetModel.objects.all().count() == 3 |
381 | 384 |
# check a second call doesn't download anything |
382 | 385 |
call_command('cron', 'hourly') |
... | ... | |
387 | 390 |
@mock.patch('passerelle.utils.Request.get') |
388 | 391 |
def test_base_adresse_command_update_97x(mocked_get, db, base_adresse_97x): |
389 | 392 |
base_adresse_97x.update_api_geo_data = lambda: None |
390 |
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.bz2') |
|
391 |
mocked_get.return_value = utils.FakedResponse(content=open(filepath, 'rb').read(), status_code=200) |
|
393 |
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz') |
|
394 |
with open(filepath, 'rb') as ban_file: |
|
395 |
mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200) |
|
392 | 396 |
call_command('cron', 'daily') |
393 |
mocked_get.assert_called_once_with('http://bano.openstreetmap.fr/BAN_odbl/BAN_odbl_974-json.bz2')
|
|
397 |
mocked_get.assert_called_once_with('https://adresse.data.gouv.fr/data/ban/adresses/latest/addok/adresses-addok-974.ndjson.gz')
|
|
394 | 398 |
assert StreetModel.objects.count() == 2 |
395 | 399 | |
396 | 400 | |
... | ... | |
398 | 402 |
@mock.patch('passerelle.utils.Request.get') |
399 | 403 |
def test_base_adresse_command_update_corsica(mocked_get, db, base_adresse_corsica): |
400 | 404 |
base_adresse_corsica.update_api_geo_data = lambda: None |
401 |
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.bz2') |
|
402 |
mocked_get.return_value = utils.FakedResponse(content=open(filepath, 'rb').read(), status_code=200) |
|
405 |
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz') |
|
406 |
with open(filepath, 'rb') as ban_file: |
|
407 |
mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200) |
|
403 | 408 |
call_command('cron', 'daily') |
404 | 409 |
assert mocked_get.call_count == 2 |
405 |
mocked_get.assert_any_call('http://bano.openstreetmap.fr/BAN_odbl/BAN_odbl_2A-json.bz2')
|
|
406 |
mocked_get.assert_any_call('http://bano.openstreetmap.fr/BAN_odbl/BAN_odbl_2B-json.bz2')
|
|
410 |
mocked_get.assert_any_call('https://adresse.data.gouv.fr/data/ban/adresses/latest/addok/adresses-addok-2A.ndjson.gz')
|
|
411 |
mocked_get.assert_any_call('https://adresse.data.gouv.fr/data/ban/adresses/latest/addok/adresses-addok-2B.ndjson.gz')
|
|
407 | 412 |
assert StreetModel.objects.count() == 0 |
408 | 413 | |
409 | 414 | |
... | ... | |
411 | 416 |
@mock.patch('passerelle.utils.Request.get') |
412 | 417 |
def test_base_adresse_command_update_multiple(mocked_get, db, base_adresse_multiple): |
413 | 418 |
base_adresse_multiple.update_api_geo_data = lambda: None |
414 |
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.bz2') |
|
415 |
mocked_get.return_value = utils.FakedResponse(content=open(filepath, 'rb').read(), status_code=200) |
|
419 |
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz') |
|
420 |
with open(filepath, 'rb') as ban_file: |
|
421 |
mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200) |
|
416 | 422 |
call_command('cron', 'daily') |
417 | 423 |
assert mocked_get.call_count == 4 |
418 |
mocked_get.assert_any_call('http://bano.openstreetmap.fr/BAN_odbl/BAN_odbl_73-json.bz2')
|
|
419 |
mocked_get.assert_any_call('http://bano.openstreetmap.fr/BAN_odbl/BAN_odbl_974-json.bz2')
|
|
420 |
mocked_get.assert_any_call('http://bano.openstreetmap.fr/BAN_odbl/BAN_odbl_2A-json.bz2')
|
|
421 |
mocked_get.assert_any_call('http://bano.openstreetmap.fr/BAN_odbl/BAN_odbl_2B-json.bz2')
|
|
424 |
mocked_get.assert_any_call('https://adresse.data.gouv.fr/data/ban/adresses/latest/addok/adresses-addok-73.ndjson.gz')
|
|
425 |
mocked_get.assert_any_call('https://adresse.data.gouv.fr/data/ban/adresses/latest/addok/adresses-addok-974.ndjson.gz')
|
|
426 |
mocked_get.assert_any_call('https://adresse.data.gouv.fr/data/ban/adresses/latest/addok/adresses-addok-2A.ndjson.gz')
|
|
427 |
mocked_get.assert_any_call('https://adresse.data.gouv.fr/data/ban/adresses/latest/addok/adresses-addok-2B.ndjson.gz')
|
|
422 | 428 |
assert StreetModel.objects.count() == 5 |
423 | 429 | |
424 | 430 |
tests/test_jobs.py | ||
---|---|---|
18 | 18 | |
19 | 19 |
@mock.patch('passerelle.utils.Request.get') |
20 | 20 |
def test_jobs(mocked_get, app, base_adresse, freezer): |
21 |
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.bz2') |
|
22 |
mocked_get.return_value = utils.FakedResponse(content=open(filepath, 'rb').read(), status_code=200) |
|
21 |
filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz') |
|
22 |
with open(filepath, 'rb') as ban_file: |
|
23 |
mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200) |
|
23 | 24 | |
24 | 25 |
freezer.move_to('2019-01-01 00:00:00') |
25 | 26 |
job = base_adresse.add_job('update_streets_data') |
... | ... | |
30 | 31 |
assert StreetModel.objects.count() == 3 |
31 | 32 | |
32 | 33 |
# don't delete streets if bano file is empty |
33 |
mocked_get.return_value = utils.FakedResponse(content='', status_code=200) |
|
34 |
mocked_get.return_value = utils.FakedResponse(content=b'', status_code=200)
|
|
34 | 35 |
freezer.move_to('2019-01-01 12:00:00') |
35 | 36 |
job = base_adresse.add_job('update_streets_data') |
36 | 37 |
assert job.status == 'registered' |
... | ... | |
43 | 44 |
'error running update_streets_data job (bano file is empty)') |
44 | 45 |
assert StreetModel.objects.count() == 3 |
45 | 46 | |
46 |
mocked_get.return_value = utils.FakedResponse(content=open(filepath, 'rb').read(), status_code=200) |
|
47 |
with open(filepath, 'rb') as ban_file: |
|
48 |
mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200) |
|
47 | 49 | |
48 | 50 |
StreetModel.objects.all().delete() |
49 | 51 | |
... | ... | |
133 | 135 |
StreetModel.objects.all().delete() |
134 | 136 |
with mock.patch('passerelle.apps.base_adresse.models.BaseAdresse.down') as down: |
135 | 137 |
down.side_effect = lambda: True |
136 |
mocked_get.return_value = utils.FakedResponse(content=open(filepath, 'rb').read(), status_code=200) |
|
138 |
with open(filepath, 'rb') as ban_file: |
|
139 |
mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200) |
|
137 | 140 |
job = base_adresse.add_job('update_streets_data') |
138 | 141 |
assert job.status == 'registered' |
139 | 142 | |
140 |
- |