Skip to content

Commit b438498

Browse files
authored
Merge pull request #1338 from TOMToolkit/1185-sanitize-dataproduct-paths
Sanitize data product paths
2 parents 8125618 + a355c3c commit b438498

2 files changed

Lines changed: 21 additions & 8 deletions

File tree

tom_dataproducts/models.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from django.conf import settings
77
from django.core.files import File
88
from django.db import models
9-
from django.utils import timezone
9+
from django.utils import timezone, text
1010
from django.core.exceptions import ValidationError
1111
from fits2image.conversions import fits_to_jpg
1212
from PIL import Image
@@ -113,10 +113,13 @@ def data_product_path(instance, filename):
113113
return clazz(instance, filename)
114114
except AttributeError:
115115
# Uploads go to MEDIA_ROOT
116+
# Slugify ensures strings are both FS and URL safe.
117+
name = text.slugify(instance.target.name)
116118
if instance.observation_record is not None:
117-
return f'{instance.target.name}/{instance.observation_record.facility}/{filename}'
119+
facility = text.slugify(instance.observation_record.facility)
120+
return f'{name}/{facility}/{filename}'
118121
else:
119-
return f'{instance.target.name}/none/{filename}'
122+
return f'{name}/none/{filename}'
120123

121124

122125
class DataProductGroup(models.Model):

tom_dataproducts/tests/tests.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from django.core.exceptions import ValidationError
1515
from django.core.files.uploadedfile import SimpleUploadedFile
1616
from django.urls import reverse
17-
from django.utils import timezone
17+
from django.utils import timezone, text
1818
from guardian.shortcuts import assign_perm
1919
import numpy as np
2020
from specutils import Spectrum1D
@@ -171,14 +171,22 @@ def test_no_path_overide(self):
171171
"""Test that the default path is used if no overide is set"""
172172
filename = 'afile.fits'
173173
path = data_product_path(self.data_product, filename)
174-
self.assertIn(f'FakeRoboticFacility/{filename}', path)
174+
self.assertIn(f'{text.slugify(FakeRoboticFacility.name)}/{filename}', path)
175175

176176
@override_settings(DATA_PRODUCT_PATH='tom_dataproducts.tests.tests.dp_path')
177177
def test_path_overide(self):
178178
"""Test that the overide path is used if set"""
179179
path = data_product_path(self.data_product, 'afile.fits')
180180
self.assertIn('new_path/afile.fits', path)
181181

182+
def test_target_name_with_slashes(self):
183+
"""Test that a target with a name such as C/2021 G2 (ATLAS) doesn't create
184+
mutiple directories in the filesystem. TOMToolkit/tom_base #1185"""
185+
self.target.name = 'C/2021 G2 (ATLAS)'
186+
self.target.save()
187+
path = data_product_path(self.data_product, 'afile.fits')
188+
self.assertEqual('c2021-g2-atlas/fakeroboticfacility/afile.fits', path)
189+
182190

183191
@override_settings(TOM_FACILITY_CLASSES=['tom_observations.tests.utils.FakeRoboticFacility'],
184192
TARGET_PERMISSIONS_ONLY=False)
@@ -309,7 +317,9 @@ def test_upload_data_for_target(self, run_data_processor_mock):
309317
},
310318
follow=True
311319
)
312-
self.assertContains(response, 'Successfully uploaded: {0}/none/afile.fits'.format(self.target.name))
320+
self.assertContains(response, 'Successfully uploaded: {0}/none/afile.fits'.format(
321+
text.slugify(self.target.name)
322+
))
313323

314324
def test_upload_data_for_observation(self, run_data_processor_mock):
315325
response = self.client.post(
@@ -326,8 +336,8 @@ def test_upload_data_for_observation(self, run_data_processor_mock):
326336
follow=True
327337
)
328338
self.assertContains(response, 'Successfully uploaded: {0}/{1}/bfile.fits'.format(
329-
self.target.name, FakeRoboticFacility.name)
330-
)
339+
text.slugify(self.target.name), text.slugify(FakeRoboticFacility.name)
340+
))
331341

332342

333343
class TestDeleteDataProducts(TestCase):

0 commit comments

Comments
 (0)