diff --git a/README.md b/README.md index a331db6..7e4da00 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ After a last verification of the files, to run with docker, just type: # First time you download the app, or sometime to refresh the image docker-compose -f docker-compose.yml -f docker-compose-dev.yml pull # Call the docker compose pull command docker-compose -f docker-compose.yml -f docker-compose-dev.yml build # Should be launched once each time you want to start the stack +docker-compose -f docker-compose.yml -f docker-compose-dev.yml run --rm django ./manage.py migrate # Do the migrations docker-compose -f docker-compose.yml -f docker-compose-dev.yml up django # Should be launched once each time you want to start the stack # Take care that no migrations are run, so you can't launch celery/celerybeat container until migration are applied. ``` @@ -155,14 +156,14 @@ Wait for the startup to finish, then, while keeping it running, go in an other shell and populate the database with the following commands: ```sh -$ docker-compose exec django /code/venv/bin/python /code/src/manage.py populatedata # Launch a shell inside django container +$ docker-compose exec django ./manage.py populatedata # Launch a shell inside django container ``` To be able to connect you need to create a super user. Execute: ```sh -$ docker-compose exec django /code/venv/bin/python3 /code/src/manage.py createsuperuser +$ docker-compose exec django ./manage.py createsuperuser ``` Your instance is now up and running. @@ -227,11 +228,11 @@ docker-compose exec django bash ## Calling Django manage commands ```sh -docker-compose exec django /code/venv/bin/python3 /code/src/manage.py shell [options] +docker-compose exec django ./manage.py shell [options] # For instance: -# docker-compose exec django /code/venv/bin/python3 /code/src/manage.py shell migrate -# docker-compose exec django /code/venv/bin/python3 /code/src/manage.py shell shell -# docker-compose exec django /code/venv/bin/python3 /code/src/manage.py shell createsuperuser +# docker-compose exec django ./manage.py shell migrate +# docker-compose exec django ./manage.py shell shell +# docker-compose exec django ./manage.py shell createsuperuser # ... ``` diff --git a/requirements.txt b/requirements.txt index def80fd..2e8e79c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,6 +8,7 @@ django-geosource>=0.4.6 terra-layer>=0.4.6 terra-bonobo-nodes>=0.3.9 django-terra-utils>=0.3.6,<0.4 +django-terra-geocrud>=0.3.28,<0.4 django-cors-headers<3.0 diff --git a/src/custom/dataloader/admin.py b/src/custom/dataloader/admin.py new file mode 100644 index 0000000..c88d31a --- /dev/null +++ b/src/custom/dataloader/admin.py @@ -0,0 +1,14 @@ +from django.conf import settings +from django.contrib import admin +from geostore import models as geostore_models +from mapbox_baselayer.admin import MapBaseLayerAdmin +from mapbox_baselayer.models import MapBaseLayer + +if settings.USE_TERRAGEOCRUD: + from terra_geocrud import models as geocrud_models, admin as geocrud_admin + admin.site.register(geocrud_models.CrudGroupView, geocrud_admin.CrudGroupViewAdmin) + admin.site.register(geocrud_models.CrudView, geocrud_admin.CrudViewAdmin) + admin.site.register(geocrud_models.AttachmentCategory, geocrud_admin.AttachmentCategoryAdmin) + admin.site.register(geostore_models.Layer, geocrud_admin.CrudLayerAdmin) + admin.site.register(geostore_models.Feature, geocrud_admin.CrudFeatureAdmin) +admin.site.register(MapBaseLayer, MapBaseLayerAdmin) diff --git a/src/custom/dataloader/geosource_callbacks.py b/src/custom/dataloader/geosource_callbacks.py index df007a5..b0da047 100644 --- a/src/custom/dataloader/geosource_callbacks.py +++ b/src/custom/dataloader/geosource_callbacks.py @@ -3,6 +3,7 @@ from django.contrib.auth.models import Group from django.contrib.gis.geos import GEOSGeometry from geostore.models import Layer, LayerGroup + from rest_framework.exceptions import MethodNotAllowed from custom.receivers import * # noqa @@ -11,24 +12,7 @@ def layer_callback(geosource): - - group_name = geosource.settings.pop('group', 'reference') - - defaults = { - 'settings': geosource.settings, - } - - layer, _ = Layer.objects.get_or_create(name=geosource.slug, defaults=defaults) - - layer_groups = Group.objects.filter(pk__in=geosource.settings.get('groups', [])) - - if set(layer.authorized_groups.all()) != set(layer_groups): - layer.authorized_groups.set(layer_groups) - - if not layer.layer_groups.filter(name=group_name).exists(): - group, _ = LayerGroup.objects.get_or_create(name=group_name) - group.layers.add(layer) - + layer = Layer.objects.get(name=geosource.slug) return layer diff --git a/src/custom/receivers.py b/src/custom/receivers.py index 76217c7..f177b27 100644 --- a/src/custom/receivers.py +++ b/src/custom/receivers.py @@ -2,9 +2,17 @@ import sys from io import BytesIO +from django.conf import settings +from django.contrib.auth.models import Group from django.core.management import call_command +from django.db.models.signals import post_save from django.dispatch import receiver +from django_geosource.models import Source, GeoJSONSource from django_geosource.signals import refresh_data_done +from geostore.models import Layer, LayerGroup +if settings.USE_TERRAGEOCRUD: + from terra_geocrud.models import CrudView, CrudViewProperty + from terra_geocrud.properties.schema import sync_layer_schema logger = logging.getLogger(__name__) @@ -20,3 +28,48 @@ def refresh_es(sender, **kwargs): except Exception: logger.error('An error occurend during indexing', exc_info=True) logger.info('End of elasticsearch indexing') + + +@receiver(post_save) +def update_layer_on_source_creation(sender, **kwargs): + obj = kwargs['instance'] + if isinstance(obj, Source): + source = obj + group_name = source.settings.pop('group', 'reference') + + defaults = { + 'settings': source.settings, + } + + layer, created = Layer.objects.get_or_create(name=source.slug, defaults=defaults, geom_type=source.geom_type) + + layer_groups = Group.objects.filter(pk__in=source.settings.get('groups', [])) + + if set(layer.authorized_groups.all()) != set(layer_groups): + layer.authorized_groups.set(layer_groups) + + if not layer.layer_groups.filter(name=group_name).exists(): + group, _ = LayerGroup.objects.get_or_create(name=group_name) + group.layers.add(layer) + + if settings.USE_TERRAGEOCRUD: + crud_view = CrudView.objects.get_or_create(layer=layer, + defaults={"name": layer.name, "order": 0})[0] + fields = source.fields.all() + for field in fields: + data_type = field.data_type + name = field.name + label = field.label + if data_type == 1: + final_type = "string" + elif data_type == 2: + final_type = "string" + elif data_type == 3: + final_type = "float" + elif data_type == 4: + final_type = "boolean" + property, created = CrudViewProperty.objects.get_or_create(view=crud_view, key=name) + property.json_schema = {"title": label, "type": final_type} + property.save() + + sync_layer_schema(crud_view) diff --git a/src/manage.py b/src/manage.py index a3b3a16..c635b68 100755 --- a/src/manage.py +++ b/src/manage.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/code/venv/bin/python import os import sys diff --git a/src/project/settings/base.py b/src/project/settings/base.py index 532c935..d1e6a5e 100644 --- a/src/project/settings/base.py +++ b/src/project/settings/base.py @@ -21,6 +21,8 @@ USE_TZ = True +USE_TERRAGEOCRUD = os.environ.get('TERRAGEOCRUD', False) + INSTALLED_APPS = ( 'terra_utils', 'django.contrib.auth', @@ -36,9 +38,20 @@ 'geostore', 'django_geosource', 'terra_layer', - 'custom.dataloader', + 'mapbox_baselayer', + 'django.contrib.admin', + 'django.contrib.messages', + 'custom.dataloader' ) +if USE_TERRAGEOCRUD: + INSTALLED_APPS += ('terra_geocrud', + 'django_object_actions', + 'template_model', + 'django_json_widget', + 'reversion', + 'sorl.thumbnail') + AUTH_USER_MODEL = 'terra_accounts.TerraUser' PROJECT_DIR = os.path.abspath('.') @@ -53,6 +66,7 @@ JWT_AUTH = { 'JWT_EXPIRATION_DELTA': timedelta(hours=1), 'JWT_ALLOW_REFRESH': True, + 'JWT_PAYLOAD_HANDLER': 'terra_accounts.jwt_payload.terra_payload_handler', } TOKEN_TIMEOUT = 3600 @@ -179,11 +193,11 @@ TILE_FLAVOR = 'smart' -MIN_TILE_ZOOM = 7 +MIN_TILE_ZOOM = 2 MAX_TILE_ZOOM = 16 +INTERNAL_GEOMETRY_SRID = 4326 TERRA_TILES_HOSTNAMES = [] # let DEBUG & CORS be overridable in prod DEBUG = False -CORS_ORIGIN_ALLOW_ALL = False diff --git a/src/project/settings/local.py.dist b/src/project/settings/local.py.dist index e816539..1e90450 100644 --- a/src/project/settings/local.py.dist +++ b/src/project/settings/local.py.dist @@ -34,3 +34,17 @@ TERRA_APPLIANCE_SETTINGS = { 'enabled_modules': ['User', 'DataSource', 'DataLayer'], # Enabled terra admin modules } +## Uncoment these lines to enable and configure geocrud and add 'CRUD' above in enabled_modules +# TERRA_GEOCRUD = { +# 'EXTENT': [2, 40, 6, 50], +# 'MBGLRENDERER_URL': os.getenv('MBGLRENDERER_URL', 'http://mbglrenderer'), +# "map": { +# "mapbox_access_token": "key_mapbox", +# "center": [3, 46], +# "zoom": 5, +# "maxZoom": 17, +# "minZoom": 3 +# }, +# "MAX_ZOOM": 17, +# } +# diff --git a/src/project/urls.py b/src/project/urls.py index 6ef79ae..12818a9 100644 --- a/src/project/urls.py +++ b/src/project/urls.py @@ -14,14 +14,20 @@ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.conf import settings +from django.contrib import admin from django.conf.urls.static import static from django.urls import include, path from custom.receivers import * # noqa urlpatterns = [ + path('', admin.site.urls), path('api/', include('terra_layer.urls')), + path('api/mapbox_baselayer/', include('mapbox_baselayer.urls')), ] if settings.DEBUG and False: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + +if settings.USE_TERRAGEOCRUD: + urlpatterns += [path('api/crud/', include('terra_geocrud.urls'))]