Skip to content

Commit

Permalink
Fix long names thumbnail SmileyChris#388
Browse files Browse the repository at this point in the history
- Do not use hash for SEO
- Truncate end of the file after generate thumbnail
- Add tests with long names
  • Loading branch information
LePetitTim committed May 22, 2020
1 parent 208057c commit e13fc8d
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
10 changes: 10 additions & 0 deletions easy_thumbnails/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,16 @@ def get_thumbnail_name(self, thumbnail_options, transparent=False,
thumbnail_options=thumbnail_options,
prepared_options=prepared_opts,
)
max_length = models.File._meta.get_field('name').max_length
if len(filename) > max_length:
additional_length = len(filename) - max_length
filename = namer_func(
thumbnailer=self,
source_filename=source_filename[::additional_length],
thumbnail_extension=extension,
thumbnail_options=thumbnail_options,
prepared_options=prepared_opts,
)
if high_resolution:
filename = self.thumbnail_highres_infix.join(
os.path.splitext(filename))
Expand Down
78 changes: 78 additions & 0 deletions easy_thumbnails/tests/test_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,31 @@ def setUp(self):
# Save a test image in both storages.
filename = self.create_image(self.storage, 'test.jpg')
self.thumbnailer = files.get_thumbnailer(self.storage, filename)
# Save a test image with a really long name in both storages
long_filename = self.create_image(self.storage, '%s.jpg' % ('*' * 251))
self.longname_thumbnailer = files.get_thumbnailer(self.storage, long_filename)

self.longname_thumbnailer.thumbnail_storage = self.storage
self.thumbnailer.thumbnail_storage = self.storage

filename = self.create_image(self.remote_storage, 'test.jpg')
self.remote_thumbnailer = files.get_thumbnailer(
self.remote_storage, filename)
long_filename = self.create_image(self.remote_storage, '%s.jpg' % ('*' * 251))
self.longname_remote_thumbnailer = files.get_thumbnailer(
self.remote_storage, long_filename)

self.remote_thumbnailer.thumbnail_storage = self.remote_storage
self.longname_remote_thumbnailer.thumbnail_storage = self.remote_storage

# Create another thumbnailer for extension test.
self.ext_thumbnailer = files.get_thumbnailer(self.storage, filename)
self.ext_thumbnailer.thumbnail_storage = self.storage

# Create another thumbnailer with long filename for extension test.
self.longname_ext_thumbnailer = files.get_thumbnailer(self.storage, long_filename)
self.longname_ext_thumbnailer.thumbnail_storage = self.storage

# Generate test transparent images.
filename = self.create_image(
self.storage, 'transparent.png', image_mode='RGBA',
Expand Down Expand Up @@ -92,6 +106,43 @@ def test_tag(self):
'<img alt="" class="fish" height="75" rel="A&amp;B" '
'src="%s" width="100" />' % local.url)

def test_tag_long_filename(self):
local = self.longname_thumbnailer.get_thumbnail({'size': (100, 100)})
remote = self.longname_remote_thumbnailer.get_thumbnail({'size': (100, 100)})

self.assertEqual(
local.tag(), '<img alt="" height="75" src="%s" width="100" '
'/>' % local.url)
self.assertEqual(
local.tag(alt='A & B'), '<img alt="A &amp; B" height="75" '
'src="%s" width="100" />' % local.url)

# Can turn off dimensions.
self.assertEqual(
remote.tag(use_size=False), '<img alt="" src="%s" />' % remote.url)

# Even a remotely generated thumbnail has the dimensions cached if it
# was just created.
self.assertEqual(
remote.tag(),
'<img alt="" height="75" src="%s" width="100" />' % remote.url)

# Future requests to thumbnails on remote storage don't get
# dimensions...
remote = self.longname_remote_thumbnailer.get_thumbnail({'size': (100, 100)})
self.assertEqual(
remote.tag(), '<img alt="" src="%s" />' % remote.url)
# ...unless explicitly requested.
self.assertEqual(
remote.tag(use_size=True),
'<img alt="" height="75" src="%s" width="100" />' % remote.url)

# All other arguments are passed through as attributes.
self.assertEqual(
local.tag(**{'rel': 'A&B', 'class': 'fish'}),
'<img alt="" class="fish" height="75" rel="A&amp;B" '
'src="%s" width="100" />' % local.url)

def test_tag_cached_dimensions(self):
settings.THUMBNAIL_CACHE_DIMENSIONS = True
self.remote_thumbnailer.get_thumbnail({'size': (100, 100)})
Expand Down Expand Up @@ -237,6 +288,23 @@ def test_high_resolution_force(self):
with Image.open(hires_thumb_file) as thumb:
self.assertEqual(thumb.size, (200, 150))

def test_high_resolution_force_off_with_longname(self):
self.longname_ext_thumbnailer.thumbnail_high_resolution = True
thumb = self.longname_ext_thumbnailer.get_thumbnail(
{'size': (100, 100), 'HIGH_RESOLUTION': False})
base, ext = path.splitext(thumb.path)
hires_thumb_file = ''.join([base + '@2x', ext])
self.assertFalse(path.exists(hires_thumb_file))

def test_high_resolution_force_with_longname(self):
thumb = self.longname_ext_thumbnailer.get_thumbnail(
{'size': (100, 100), 'HIGH_RESOLUTION': True})
base, ext = path.splitext(thumb.path)
hires_thumb_file = ''.join([base + '@2x', ext])
self.assertTrue(path.isfile(hires_thumb_file))
with Image.open(hires_thumb_file) as thumb:
self.assertEqual(thumb.size, (200, 150))

def test_highres_infix(self):
self.ext_thumbnailer.thumbnail_high_resolution = True
self.ext_thumbnailer.thumbnail_highres_infix = '_2x'
Expand All @@ -247,6 +315,16 @@ def test_highres_infix(self):
with Image.open(hires_thumb_file) as thumb:
self.assertEqual(thumb.size, (200, 150))

def test_highres_infix_with_longname(self):
self.longname_ext_thumbnailer.thumbnail_high_resolution = True
self.longname_ext_thumbnailer.thumbnail_highres_infix = '_2x'
thumb = self.longname_ext_thumbnailer.get_thumbnail({'size': (100, 100)})
base, ext = path.splitext(thumb.path)
hires_thumb_file = ''.join([base + '_2x', ext])
self.assertTrue(path.isfile(hires_thumb_file))
with Image.open(hires_thumb_file) as thumb:
self.assertEqual(thumb.size, (200, 150))

@unittest.skipIf(
'easy_thumbnails.optimize' not in settings.INSTALLED_APPS,
'optimize app not installed')
Expand Down

0 comments on commit e13fc8d

Please sign in to comment.