Skip to content

Commit

Permalink
Merge pull request #115 from Terralego/delete_pictures_delete_feature
Browse files Browse the repository at this point in the history
Add delete properties pictures on deletion features
  • Loading branch information
LePetitTim authored Feb 15, 2022
2 parents e80dcfe + 6d81932 commit a455568
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CHANGELOG
1.0.23+dev (XXXX-XX-XX)
---------------------------

* Add deletion signal delete properties pictures and thumbnails

1.0.23 (2022-02-11)
---------------------------
Expand Down
18 changes: 15 additions & 3 deletions terra_geocrud/properties/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,25 @@ def delete_old_picture_property(file_prop, old_properties):
delete(old_storage_file_path)


def store_feature_files(feature, old_properties=None):
""" Handle base64 encoded files to django storage. Use fake base64 to compatibility with react-json-schema """
fake_content = 'R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='
def get_files_properties(feature):
files_properties = [
key for key, value in feature.layer.schema['properties'].items()
if feature.layer.schema['properties'][key].get('format') == 'data-url'
]
return files_properties


def delete_feature_files(feature):
files_properties = get_files_properties(feature)
if files_properties:
for file_prop in files_properties:
delete_old_picture_property(file_prop, feature.properties)


def store_feature_files(feature, old_properties=None):
""" Handle base64 encoded files to django storage. Use fake base64 to compatibility with react-json-schema """
fake_content = 'R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='
files_properties = get_files_properties(feature)
if files_properties:
storage = get_storage()
for file_prop in files_properties:
Expand Down
7 changes: 7 additions & 0 deletions terra_geocrud/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from geostore.helpers import execute_async_func
from geostore.models import Feature, LayerRelation
from geostore.signals import save_feature, save_layer_relation
from terra_geocrud.properties.files import delete_feature_files
from terra_geocrud.tasks import (feature_update_relations_and_properties, layer_relations_set_destinations,
feature_update_relations_origins, feature_update_destination_properties)

Expand Down Expand Up @@ -42,8 +43,14 @@ def save_layer_relation(sender, instance, **kwargs):
execute_async_func(layer_relations_set_destinations, (instance.pk, ))


@receiver(post_delete, sender=Feature, dispatch_uid='delete_files_feature')
def delete_files_feature(sender, instance, **kwargs):
delete_feature_files(instance)


@receiver(post_delete, sender=Feature, dispatch_uid='delete_feature')
def delete_feature(sender, instance, **kwargs):
# save base64 file content to storage
if app_settings.GEOSTORE_RELATION_CELERY_ASYNC:
kwargs['relation_id'] = None
kwargs.pop('signal')
Expand Down
47 changes: 46 additions & 1 deletion terra_geocrud/tests/test_signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,21 @@
from django.contrib.gis.geos import LineString, Polygon

from terra_geocrud.models import CrudViewProperty
from terra_geocrud.properties.files import get_storage, store_feature_files
from terra_geocrud.tasks import (
ConcurrentPropertyModificationError,
feature_update_relations_and_properties,
feature_update_relations_origins,
feature_update_destination_properties,
sync_properties_relations_destination,
)
from terra_geocrud.thumbnail_backends import ThumbnailDataFileBackend

from terra_geocrud.tests.factories import CrudViewFactory
from ..signals import save_feature

thumbnail_backend = ThumbnailDataFileBackend()


class AsyncSideEffect(object):
def add_side_effect_async(self, mocked):
Expand All @@ -31,6 +36,46 @@ def side_effect_async(async_func, args=()):
mocked.side_effect = side_effect_async


@patch('terra_geocrud.tasks.feature_update_relations_and_properties.delay')
@patch('terra_geocrud.signals.execute_async_func')
class DeletionFeatureDeletePictureTest(TestCase):
def setUp(self):

layer = LayerFactory.create(geom_type=GeometryTypes.LineString,
schema={"type": "object",
"required": ["name", ],
"properties": {"name": {"type": "string", "title": "Name"}}
})
self.crud_view = CrudViewFactory(layer=layer)
self.prop_name = CrudViewProperty.objects.create(
view=self.crud_view, key="picture",
editable=True,
json_schema={'type': "string",
'title': "Picture",
'format': "data-url"}
)
sync_layer_schema(self.crud_view)
self.feature = Feature.objects.create(
layer=self.crud_view.layer,
properties={'name': 'foo',
'picture': "data:image/png;name=titre_laromieu-fondblanc.jpg;base64,iVBORw0KGgoAAAANSUhEUgAAAA"
"EAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="},
geom=LineString((0, 0), (1, 0))
)
store_feature_files(self.feature, {})
self.storage = get_storage()
self.property_value = self.feature.properties.get('picture')
self.storage_file_path = self.property_value.split(';name=')[-1].split(';')[0]
self.thumbnail = thumbnail_backend.get_thumbnail(self.storage_file_path, "500x500", crop='noop', upscale=False)
self.assertTrue(self.storage.exists(self.thumbnail.name))
self.assertTrue(self.storage.exists(self.storage_file_path))

def test_signal_feature_delete_pictures(self, async_mocked, mock_delay):
self.feature.delete()
self.assertFalse(self.storage.exists(self.thumbnail.name))
self.assertFalse(self.storage.exists(self.storage_file_path))


@patch('terra_geocrud.tasks.feature_update_relations_and_properties.delay')
@patch('terra_geocrud.signals.execute_async_func')
@patch('geostore.settings.GEOSTORE_RELATION_CELERY_ASYNC', new_callable=PropertyMock)
Expand Down Expand Up @@ -70,7 +115,7 @@ def setUp(self):
geom=LineString((0, 0), (10, 10))
)

def test_signal(self, property_mocked, async_mocked, mock_delay):
def test_signal_property_update(self, property_mocked, async_mocked, mock_delay):
property_mocked.return_value = True
self.add_side_effect_async(async_mocked)
self.feature.refresh_from_db()
Expand Down
3 changes: 2 additions & 1 deletion terra_geocrud/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,8 @@ def test_list_endpoint(self):
response_list = self.client.get(reverse('feature-list', args=(self.crud_view.layer_id,)),
format="json")
data = response_list.json()
self.assertEqual(len(data), self.crud_view.layer.features.count())
features = self.crud_view.layer.features.all()
self.assertEqual(len(data), len(features))

def test_property_detail_display_with_groups(self):
response_detail = self.client.get(reverse('feature-detail',
Expand Down

0 comments on commit a455568

Please sign in to comment.