From 7b78677cb865dc17932ba28e46eb33b5933806e5 Mon Sep 17 00:00:00 2001 From: Bruno Martin Date: Thu, 12 Apr 2018 20:13:46 -0300 Subject: [PATCH 1/7] fix mixin filter bug --- mapaguarani/core/views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mapaguarani/core/views.py b/mapaguarani/core/views.py index 2806c18..23ae07d 100644 --- a/mapaguarani/core/views.py +++ b/mapaguarani/core/views.py @@ -136,7 +136,7 @@ class SimpleIndigenousVillageViewSetWithPosition(FilterLayersBySiteAndUserAuthen class FilterVillageMixin(object): def get_queryset(self): - queryset = IndigenousVillage.objects.all() + queryset = super().get_queryset() guarani_presence = self.request.query_params.get('guarani_presence', None) if guarani_presence is not None: if guarani_presence in ('False', 'false'): @@ -149,7 +149,7 @@ def get_queryset(self): class IndigenousVillageGeojsonView(FilterVillageMixin, FilterLayersBySiteAndUserAuthenticatedMixin, viewsets.ReadOnlyModelViewSet): - queryset = IndigenousVillage.objects.none() + queryset = IndigenousVillage.objects.all() serializer_class = SimpleIndigenousGeojsonVillageSerializer @@ -159,7 +159,7 @@ class IndigenousVillageKMLView(KMLViewMixin, IndigenousVillageGeojsonView): class IndigenousVillageExportView(FilterVillageMixin, FilterLayersBySiteAndUserAuthenticatedMixin, PandasView): - queryset = IndigenousVillage.objects.none() + queryset = IndigenousVillage.objects.all() serializer_class = IndigenousVillageExportSerializer From 254ef0229ef4af4b2ca4e2a5aedab1d3741581e7 Mon Sep 17 00:00:00 2001 From: Bruno Martin Date: Fri, 13 Apr 2018 12:45:02 -0300 Subject: [PATCH 2/7] django anymail mailgun configs in productions settings --- mapaguarani/config/production.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/mapaguarani/config/production.py b/mapaguarani/config/production.py index 96ac989..f437a11 100644 --- a/mapaguarani/config/production.py +++ b/mapaguarani/config/production.py @@ -39,15 +39,20 @@ # EMAIL # ------------------------------------------------------------------------------ -# DEFAULT_FROM_EMAIL = env('DJANGO_DEFAULT_FROM_EMAIL', -# default='') -EMAIL_HOST = env("DJANGO_EMAIL_HOST", default='smtp.sendgrid.com') -# EMAIL_HOST_PASSWORD = env("SENDGRID_PASSWORD") -# EMAIL_HOST_USER = env('SENDGRID_USERNAME') -# EMAIL_PORT = env.int("EMAIL_PORT", default=587) -# EMAIL_SUBJECT_PREFIX = env("EMAIL_SUBJECT_PREFIX", default='[{{cookiecutter.project_name}}] ') -# EMAIL_USE_TLS = True -# SERVER_EMAIL = EMAIL_HOST_USER +## EMAIL +# ------------------------------------------------------------------------------ +DEFAULT_FROM_EMAIL = env('DJANGO_DEFAULT_FROM_EMAIL', + default='') +EMAIL_SUBJECT_PREFIX = env('DJANGO_EMAIL_SUBJECT_PREFIX', default='') +SERVER_EMAIL = env('DJANGO_SERVER_EMAIL', default=DEFAULT_FROM_EMAIL) + +# Anymail with Mailgun +INSTALLED_APPS += ['anymail', ] +ANYMAIL = { + 'MAILGUN_API_KEY': env('DJANGO_MAILGUN_API_KEY'), + 'MAILGUN_SENDER_DOMAIN': env('MAILGUN_SENDER_DOMAIN') +} +EMAIL_BACKEND = 'anymail.backends.mailgun.EmailBackend' # TEMPLATE CONFIGURATION # ------------------------------------------------------------------------------ From 3fb4284c2c7976fc891bdadb4761a3b88bfdee31 Mon Sep 17 00:00:00 2001 From: Bruno Martin Date: Fri, 13 Apr 2018 16:03:01 -0300 Subject: [PATCH 3/7] refactor import lands layer to work with more general cases --- .../management/commands/import_lands_layer.py | 199 ++++++------------ 1 file changed, 64 insertions(+), 135 deletions(-) diff --git a/mapaguarani/core/management/commands/import_lands_layer.py b/mapaguarani/core/management/commands/import_lands_layer.py index 3507460..1e7107b 100644 --- a/mapaguarani/core/management/commands/import_lands_layer.py +++ b/mapaguarani/core/management/commands/import_lands_layer.py @@ -15,121 +15,86 @@ def handle(self, *args, **options): ds = DataSource(shapefile_path) source_layer = ds[0] - lands_layer, _ = MapLayer.objects.get_or_create(name='Terras Indígenas') - lands_layer.description = 'Camada de Terras Indígenas dos povos Guarani' + lands_layer, _ = MapLayer.objects.get_or_create(name='Terras Indígenas - Povos não Guaranis') + lands_layer.description = 'Camada de Terras Indígenas' lands_layer.save() - def _get_ethnic_group(groups): - - groups_names = [] - if ',' in groups: - group_list = groups.split(',') - else: - group_list = groups.split() - if len(group_list) == 1: - groups_names.append(group_list[0]) - elif 'e' in group_list and len(group_list) == 3: - groups_names.append(group_list[0]) - groups_names.append(group_list[2]) - elif len(group_list) == 4: - groups_names.append(group_list[0][:-1]) - groups_names.append(group_list[1]) - groups_names.append(group_list[3]) - elif len(group_list) == 2 or len(group_list) == 3: - groups_names = group_list - else: - print('EthnicGroup:') - print(group_list) - - for group_name in groups_names: - try: - yield EthnicGroup.objects.get(name=group_name) - except EthnicGroup.DoesNotExist: - print('Não achou EthnicGroup: ' + group_name) - - def _get_ethnic_subgroup(groups): + def _get_ethnic_group(groups, create=False): + """ + The ethnic groups names must be separated by coma + """ groups_names = [] - if ',' in groups: - group_list = groups.split(',') - else: - group_list = groups.split() - if len(group_list) == 1: - if '/' not in group_list[0]: - groups_names.append(group_list[0]) + + for group_name in groups.split(','): + group_name = group_name.strip() + if not group_name: + return + if create: + ethnic_group, created = EthnicGroup.objects.get_or_create(name=group_name) + if created: + self.stdout.write('O povo {0} foi criado.'.format(group_name)) + yield ethnic_group + else: + try: + yield EthnicGroup.objects.get(name=group_name) + except EthnicGroup.DoesNotExist: + self.stdout.write('O povo {0} não foi encontrato e não será criado, por favor verifique o arquivo de importação.'.format(group_name)) + + + def _get_ethnic_subgroup(groups, create=False): + """ + The ethnic subgroups names must be separated by coma + """ + for group_name in groups.split(','): + group_name = group_name.strip() + if create: + ethnic_subgroup, _ = ProminentEthnicSubGroup.objects.get_or_create(name=group_name) + yield ethnic_subgroup else: - group_list = groups.split('/') - if len(group_list) == 2: - groups_names = group_list - elif '/' in groups: - if group_list and len(group_list) == 3: - groups_names.append(group_list[0]) - if '/' in group_list[2]: - group_list2 = group_list[2].split('/') - groups_names.append(group_list2[0]) - groups_names.append(group_list2[1]) - else: - groups_names.append(group_list[2]) - elif len(group_list) == 2: - groups_names.append(group_list[0]) - if '/'in group_list[1]: - groups_names.append(group_list[1][1:]) - else: - groups_names.append(group_list[1]) - elif len(group_list) == 4: - groups_names.append(group_list[0]) - groups_names.append(group_list[2]) - if '/'in group_list[3]: - groups_names.append(group_list[3][1:]) - else: - groups_names.append(group_list[3]) - elif len(group_list) == 2 or len(group_list) == 3: - groups_names = group_list - else: - print(group_list) - - for group_name in groups_names: - try: - yield ProminentEthnicSubGroup.objects.get(name=group_name) - except ProminentEthnicSubGroup.DoesNotExist: - print('Não achou: ' + group_name) - print(groups) - print('\n') - - def _get_land_tenure(name): - land_tenure, _ = LandTenure.objects.get_or_create(name=name) - return land_tenure - - def _get_land_tenure_status(name): - land_tenure_status, _ = LandTenureStatus.objects.get_or_create(name=name) - return land_tenure_status + try: + yield EthnicGroup.objects.get(name=group_name) + except ProminentEthnicSubGroup.DoesNotExist: + self.stdout.write('O subgrupo Guarani {0} não foi encontrato e não será criado, por favor verifique o arquivo de importação.'.format(group_name)) for feat in source_layer: - official_area = feat.get('AREA').replace(".", "").replace(",", ".") - if official_area: + official_area = feat.get('AREA') + if isinstance(official_area, str): + official_area.replace(".", "").replace(",", ".") official_area = float(official_area) - else: + if not official_area: official_area = 0.0 kwargs = { 'layer': lands_layer, 'name': feat.get('TERRA_INDI'), - 'other_names': feat.get('OUTRAS_DEN'), + # 'other_names': feat.get('OUTRAS_DEN'), 'official_area': official_area, - 'claim': feat.get('REIVINDICA'), - 'demand': feat.get('DEMANDA'), + # 'claim': feat.get('REIVINDICA'), + # 'demand': feat.get('DEMANDA'), 'source': feat.get('FONTE'), - 'private_comments': feat.get('OBS_PRIVAD'), - 'public_comments': feat.get('OBS_PUBLIC'), - 'guarani_exclusive_possession_area_portion': float(feat.get('PORCAO_ARE')), - 'others_exclusive_possession_area_portion': float(feat.get('PORCAO_AR2')), - + # 'private_comments': feat.get('OBS_PRIVAD'), + # 'public_comments': feat.get('OBS_PUBLIC'), + # 'guarani_exclusive_possession_area_portion': float(feat.get('PORCAO_ARE')), + # 'others_exclusive_possession_area_portion': float(feat.get('PORCAO_AR2')), # 'associated_land': feat.get('TERRAS_ASS'), } indigenous_land = IndigenousLand(**kwargs) - indigenous_land.geometry = feat.geom.wkt + land_tenure = feat.get('SITUACAO_F') + if land_tenure == 'Em Estudo': + land_tenure ='Em estudo' + if not LandTenure.objects.filter(name=land_tenure).exists(): + raise(BaseException('Situação fundiária não encontrata! NOME: {0} STATUS: {1}'.format(feat.get('TERRA_INDI'), land_tenure))) + indigenous_land.land_tenure = LandTenure.objects.get(name=land_tenure) + + land_tenure_status = feat.get('STATUS_REV') + if not LandTenureStatus.objects.filter(name=land_tenure_status).exists(): + raise(BaseException('Status de revisão fundiária não encontrata: {}'.format(land_tenure_status))) + indigenous_land.land_tenure_status = LandTenureStatus.objects.get(name=land_tenure_status) + + indigenous_land.geometry = feat.geom.wkt try: # try to save as MultPolygon indigenous_land.save() @@ -141,49 +106,13 @@ def _get_land_tenure_status(name): indigenous_land.save() # self.stdout.write('Terra indígena: ' + indigenous_land.name + 'Posição convertida de Polígono para Multipolígono.') - ethnic_groups = _get_ethnic_group(feat.get('GRUPO_ETNI')) + ethnic_groups = _get_ethnic_group(feat.get('GRUPO_ETNI'), create=True) for group in ethnic_groups: indigenous_land.ethnic_groups.add(group) - ethnic_subgroups = _get_ethnic_subgroup(feat.get('SUBGRUPO_P')) - for ethnic_subgroup in ethnic_subgroups: - indigenous_land.prominent_subgroup.add(ethnic_subgroup) - - land_tenure = feat.get('SITUACAO_F') - if land_tenure == 'Sem Providências': - indigenous_land.land_tenure = _get_land_tenure('Sem Providências') - elif land_tenure in ['Regularizada', 'Regularizada (Em revisão de limites)']: - indigenous_land.land_tenure = _get_land_tenure('Regularizada') - elif land_tenure in ['Desapropriada', 'Desapropriada (Reivindicação de Identificação)']: - indigenous_land.land_tenure = _get_land_tenure('Desapropriada') - elif land_tenure in ['Em processo de desapropriação', 'Em processo de despropriação pelo Estado.', - 'Área em processo de despropriação pelo Estado.', 'Em processo de Desapropriação.', - 'Em processo de Desapropriação']: - indigenous_land.land_tenure = _get_land_tenure('Em processo de desapropriação') - elif land_tenure == 'Delimitada': - indigenous_land.land_tenure = _get_land_tenure('Delimitada') - elif land_tenure == 'Em estudo': - indigenous_land.land_tenure = _get_land_tenure('Em estudo') - elif land_tenure == 'Declarada': - indigenous_land.land_tenure = _get_land_tenure('Declarada') - elif land_tenure in ['Adquirida', 'Dominial Indígena']: - indigenous_land.land_tenure = _get_land_tenure('Adquirida') - elif land_tenure == 'Homologada': - indigenous_land.land_tenure = _get_land_tenure('Homologada') - else: - self.stdout.write('Situação fundiária não encontrata! NOME: ' + feat.get('TERRA_INDI') + 'STATUS: ' + land_tenure) - - land_tenure_status = feat.get('STATUS_REV') - if land_tenure_status == 'Sem Revisão': - indigenous_land.land_tenure_status = _get_land_tenure_status('Sem Revisão') - elif land_tenure_status == 'Não Delimitada': - indigenous_land.land_tenure_status = _get_land_tenure_status('Não Delimitada') - elif land_tenure_status == 'Terra Revisada': - indigenous_land.land_tenure_status = _get_land_tenure_status('Terra Revisada') - elif land_tenure_status == 'Terra Original': - indigenous_land.land_tenure_status = _get_land_tenure_status('Terra Original') - else: - self.stdout.write('Status de revisão fundiária não encontrata: ' + land_tenure_status) + # ethnic_subgroups = _get_ethnic_subgroup(feat.get('SUBGRUPO_P')) + # for ethnic_subgroup in ethnic_subgroups: + # indigenous_land.prominent_subgroup.add(ethnic_subgroup) indigenous_land.save() From e427658c8b72edafd0df828263666424846d9b34 Mon Sep 17 00:00:00 2001 From: Bruno Martin Date: Fri, 13 Apr 2018 16:04:18 -0300 Subject: [PATCH 4/7] use protobuf layers for boundaries --- mapaguarani/static/js/directives.js | 45 ++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/mapaguarani/static/js/directives.js b/mapaguarani/static/js/directives.js index 5eebd36..dd2d0fd 100644 --- a/mapaguarani/static/js/directives.js +++ b/mapaguarani/static/js/directives.js @@ -45,13 +45,44 @@ var mapbox_hybrid = L.tileLayer(mapbox_url, {mapid: 'mapbox.streets-satellite', access_token: access_token, pane: 'base_tiles'}); // Official layers - var default_host = window.location.hostname; - var protected_areas_tile = L.tileLayer('http://' + default_host + ':4000/protected_areas_baseprotectedarea/{z}/{x}/{y}.png', {}); - var boundaries_cities_tile = L.tileLayer('http://' + default_host + ':4000/boundaries_city/{z}/{x}/{y}.png', { - zIndex: 40 - }); - var boundaries_states_tile = L.tileLayer('http://' + default_host + ':4000/boundaries_state/{z}/{x}/{y}.png', {}); - var boundaries_countries_tile = L.tileLayer('http://' + default_host + ':4000/boundaries_country/{z}/{x}/{y}.png', {}); + var ProtectedAreaTileOptions = { + pane: 'base_tiles', + vectorTileLayerStyles: { + lands: function(properties, zoom) { + var styles = { + weight: 2, + fillColor: '#74c476', + color: '#74c476', + fillOpacity: 0.4, + opacity: 0.7, + fill: true, + }; + return styles + }, + }, + }; + var protected_areas_tile = L.vectorGrid.protobuf('tiles/protected_areas/{z}/{x}/{y}.pbf', ProtectedAreaTileOptions); + + var boundariesTilesOptions = { + pane: 'base_tiles', + vectorTileLayerStyles: { + lands: function(properties, zoom) { + var styles = { + weight: 2, + fillColor: '#b2e2e2;', + color: '#b2e2e2;', + // fillOpacity: 0.4, + // opacity: 0.7, + // fill: true, + }; + return styles + }, + }, + }; + + var boundaries_cities_tile = L.vectorGrid.protobuf('tiles/cities/{z}/{x}/{y}.pbf', boundariesTilesOptions); + var boundaries_states_tile = L.vectorGrid.protobuf('tiles/states/{z}/{x}/{y}.pbf', boundariesTilesOptions); + var boundaries_countries_tile = L.vectorGrid.protobuf('tiles/countries/{z}/{x}/{y}.pbf', boundariesTilesOptions); /* * Loading message From e9ba9b9d012ac7c906a363060948900252f899d0 Mon Sep 17 00:00:00 2001 From: Laury Bueno Date: Fri, 13 Apr 2018 16:39:08 -0300 Subject: [PATCH 5/7] [Prod] Fix anymail import --- mapaguarani/config/production.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapaguarani/config/production.py b/mapaguarani/config/production.py index f437a11..8ba5be5 100644 --- a/mapaguarani/config/production.py +++ b/mapaguarani/config/production.py @@ -47,7 +47,7 @@ SERVER_EMAIL = env('DJANGO_SERVER_EMAIL', default=DEFAULT_FROM_EMAIL) # Anymail with Mailgun -INSTALLED_APPS += ['anymail', ] +INSTALLED_APPS += ('anymail', ) ANYMAIL = { 'MAILGUN_API_KEY': env('DJANGO_MAILGUN_API_KEY'), 'MAILGUN_SENDER_DOMAIN': env('MAILGUN_SENDER_DOMAIN') From caa785b9f401b57d91f4c6b125a189ca019ebf29 Mon Sep 17 00:00:00 2001 From: Laury Bueno Date: Fri, 13 Apr 2018 17:48:00 -0300 Subject: [PATCH 6/7] [Prod] mkdir should not fail if the directory already exists --- compose/production/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compose/production/Dockerfile b/compose/production/Dockerfile index f442ada..4be47dc 100644 --- a/compose/production/Dockerfile +++ b/compose/production/Dockerfile @@ -49,11 +49,11 @@ RUN chown django /entrypoint.sh # Install js dependencies COPY bower.json . RUN bower --allow-root install -RUN mkdir /app && mv bower_components /app/ +RUN mkdir -p /app && mv bower_components /app/ COPY . /app -RUN mkdir /app/staticfiles +RUN mkdir -p /app/staticfiles # env.example must be used during build to provide a valid environment RUN export $(cat /app/env.example | grep -v ^# | xargs) && \ From 9beb1b52f40c68beab08d1f159a0ace7d8de2c90 Mon Sep 17 00:00:00 2001 From: Laury Bueno Date: Fri, 13 Apr 2018 17:48:24 -0300 Subject: [PATCH 7/7] [Prod] Mailgun variables added to the example environment --- env.example | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/env.example b/env.example index bc0d686..b8d869f 100644 --- a/env.example +++ b/env.example @@ -12,6 +12,10 @@ DJANGO_ACCOUNT_ALLOW_REGISTRATION=True # Sentry DJANGO_SENTRY_DSN= +# Mailgun +DJANGO_MAILGUN_API_KEY=example +MAILGUN_SENDER_DOMAIN=example.com + REDIS_URL= COURIER_ONESIGNAL_USER_ID=