Skip to content

Commit f919cbf

Browse files
authored
fix: Reduce number of thumbnails created for admin, avoid admin thumbnails for svg files (#1490)
* Fix #1377 * Simplify admin thumbnails sizes to 40, 80, 160. No thumbnails for svg in the admin. * Update settings * Fix undefined variable add_attrs * Dynamic css for new setting `FILER_THUMBNAIL_ICON_SIZE` * Replace SVG by icon if larger than 1MB (can be changed by setting) * Dynamic folder icon size * Default sizes 40, and 120px * Update folderadmin.py for better naming
1 parent 01702d8 commit f919cbf

File tree

16 files changed

+89
-54
lines changed

16 files changed

+89
-54
lines changed

filer/admin/clipboardadmin.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
from django.core.exceptions import ValidationError
33
from django.forms.models import modelform_factory
44
from django.http import JsonResponse
5-
from django.urls import path
5+
from django.urls import path, reverse
66
from django.utils.translation import gettext_lazy as _
77
from django.views.decorators.csrf import csrf_exempt
88

99
from .. import settings as filer_settings
1010
from ..models import Clipboard, ClipboardItem, Folder
11+
from ..settings import FILER_THUMBNAIL_ICON_SIZE
1112
from ..utils.files import handle_request_files_upload, handle_upload
1213
from ..utils.loader import load_model
1314
from ..validation import validate_upload
@@ -141,14 +142,10 @@ def ajax_upload(request, folder_id=None):
141142
}
142143
# prepare preview thumbnail
143144
if isinstance(file_obj, Image):
144-
thumbnail_180_options = {
145-
'size': (180, 180),
146-
'crop': True,
147-
'upscale': True,
148-
}
149-
thumbnail_180 = file_obj.file.get_thumbnail(
150-
thumbnail_180_options)
151-
data['thumbnail_180'] = thumbnail_180.url
145+
data['thumbnail_180'] = reverse(
146+
f"admin:filer_{file_obj._meta.model_name}_fileicon",
147+
args=(file_obj.pk, FILER_THUMBNAIL_ICON_SIZE),
148+
)
152149
data['original_image'] = file_obj.url
153150
return JsonResponse(data)
154151
except Exception as error:

filer/admin/folderadmin.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
from .. import settings
3131
from ..cache import clear_folder_permission_cache
3232
from ..models import File, Folder, FolderPermission, FolderRoot, ImagesWithMissingData, UnsortedImages, tools
33-
from ..settings import FILER_IMAGE_MODEL, FILER_PAGINATE_BY, TABLE_LIST_TYPE
33+
from ..settings import (
34+
FILER_IMAGE_MODEL, FILER_PAGINATE_BY, FILER_TABLE_ICON_SIZE, FILER_THUMBNAIL_ICON_SIZE, TABLE_LIST_TYPE,
35+
)
3436
from ..thumbnail_processors import normalize_subject_location
3537
from ..utils.compatibility import get_delete_permission
3638
from ..utils.filer_easy_thumbnails import FilerActionThumbnailer
@@ -271,11 +273,13 @@ def directory_listing(self, request, folder_id=None, viewtype=None):
271273

272274
list_type = get_directory_listing_type(request) or settings.FILER_FOLDER_ADMIN_DEFAULT_LIST_TYPE
273275
if list_type == TABLE_LIST_TYPE:
274-
size = "40x40" # Prefetch thumbnails for listing
275-
size_x2 = "80x80"
276+
# Prefetch thumbnails for table view
277+
size = f"{FILER_TABLE_ICON_SIZE}x{FILER_TABLE_ICON_SIZE}"
278+
size_x2 = f"{2 * FILER_TABLE_ICON_SIZE}x{2 * FILER_TABLE_ICON_SIZE}"
276279
else:
277-
size = "160x160" # Prefetch thumbnails for thumbnail view
278-
size_x2 = "320x320"
280+
# Prefetch thumbnails for thumbnail view
281+
size = f"{FILER_THUMBNAIL_ICON_SIZE}x{FILER_THUMBNAIL_ICON_SIZE}"
282+
size_x2 = f"{2 * FILER_THUMBNAIL_ICON_SIZE}x{2 * FILER_THUMBNAIL_ICON_SIZE}"
279283

280284
# Check actions to see if any are available on this changelist
281285
actions = self.get_actions(request)
@@ -467,6 +471,7 @@ def directory_listing(self, request, folder_id=None, viewtype=None):
467471
'show_result_count': show_result_count,
468472
'folder_children': folder_qs,
469473
'folder_files': file_qs,
474+
'thumbnail_size': FILER_TABLE_ICON_SIZE if list_type == TABLE_LIST_TYPE else FILER_THUMBNAIL_ICON_SIZE,
470475
'limit_search_to_folder': limit_search_to_folder,
471476
'is_popup': popup_status(request),
472477
'filer_admin_context': AdminContext(request),

filer/cache.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import typing
22

3-
from django.core.cache import cache
4-
53
from django.contrib.auth import get_user_model
4+
from django.core.cache import cache
65

76

87
User = get_user_model()

filer/migrations/0001_squashed_0016_alter_folder_index_together_remove_folder_level_and_more.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Generated by Django 3.2.25 on 2024-08-19 14:49
22

3+
import django.db.models.deletion
34
from django.conf import settings
45
from django.db import migrations, models
5-
import django.db.models.deletion
6+
67
import filer.fields.multistorage_file
78
import filer.models.filemodels
89
import filer.models.mixins

filer/models/abstract.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import logging
22

33
from django.conf import settings
4-
from django.core.checks import Warning, register as register_check
4+
from django.core.checks import Warning
5+
from django.core.checks import register as register_check
56
from django.core.exceptions import ValidationError
67
from django.db import models
78
from django.utils.functional import cached_property
89
from django.utils.translation import gettext_lazy as _
910

10-
1111
import easy_thumbnails.utils
1212
from easy_thumbnails.VIL import Image as VILImage
1313
from PIL.Image import MAX_IMAGE_PIXELS

filer/models/foldermodels.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
from django.utils.translation import gettext_lazy as _
1111

1212
from .. import settings as filer_settings
13-
from . import mixins
1413
from ..cache import get_folder_permission_cache, update_folder_permission_cache
14+
from . import mixins
1515

1616

1717
class FolderPermissionManager(models.Manager):

filer/private/sass/components/_navigator.scss

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,6 @@ body {
7777
// removes padding to make sure that column has correct height #664
7878
padding-top: 0 !important;
7979
padding-bottom: 0 !important;
80-
img {
81-
width: 40px;
82-
height: auto;
83-
}
8480
}
8581
.column-action {
8682
text-align: center;
@@ -732,17 +728,17 @@ body {
732728
float: left;
733729
display: inline-block;
734730
padding: 10px;
735-
width: 125px;
736-
height: 125px;
731+
width: calc(var(--thumbnail-size, 120px) + 5px);
732+
height: calc(var(--thumbnail-size, 120px) + 5px);
737733
border: 1px solid $gray-lighter;
738734
margin: 16px 12px;
739735
background-color: $white;
740736
position: relative;
741737
overflow: hidden;
742738
.thumbnail-file-item-box {
743739
padding: 10px;
744-
width: 125px;
745-
height: 125px;
740+
width: calc(var(--thumbnail-size, 120px) + 5px);
741+
height: calc(var(--thumbnail-size, 120px) + 5px);
746742
border: 1px solid $gray-lighter;
747743
margin: 16px 12px;
748744
background-color: $white;
@@ -791,8 +787,8 @@ body {
791787
}
792788
.thumbnail-file-item {
793789
float: none;
794-
width: 147px;
795-
height: 200px;
790+
width: calc(var(--thumbnail-size, 120px) + 27px);
791+
height: calc(var(--thumbnail-size, 120px) + 80px);
796792
border: 0;
797793
padding: 0;
798794
background-color: transparent;

filer/settings.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import os
33

44
from django.conf import settings
5-
from django.core.exceptions import ImproperlyConfigured
65
from django.utils.module_loading import import_string as get_storage_class
76
from django.utils.translation import gettext_lazy as _
87

@@ -38,20 +37,24 @@
3837

3938
FILER_PAGINATE_BY = getattr(settings, 'FILER_PAGINATE_BY', 100)
4039

40+
if hasattr(settings, "FILER_ADMIN_ICON_SIZES"):
41+
logger.warning("FILER_ADMIN_ICON_SIZES is deprecated and will be removed in the future.")
42+
4143
_ICON_SIZES = getattr(settings, 'FILER_ADMIN_ICON_SIZES', ('16', '32', '48', '64'))
42-
if not _ICON_SIZES:
43-
raise ImproperlyConfigured('Please, configure FILER_ADMIN_ICON_SIZES')
4444
# Reliably sort by integer value, but keep icon size as string.
4545
# (There is some code in the wild that depends on this being strings.)
4646
FILER_ADMIN_ICON_SIZES = [str(i) for i in sorted([int(s) for s in _ICON_SIZES])]
4747

48-
# Filer admin templates have specific icon sizes hardcoded: 32 and 48.
49-
_ESSENTIAL_ICON_SIZES = ('32', '48')
50-
if not all(x in FILER_ADMIN_ICON_SIZES for x in _ESSENTIAL_ICON_SIZES):
51-
logger.warn(
52-
"FILER_ADMIN_ICON_SIZES has not all of the essential icon sizes "
53-
"listed: {}. Some icons might be missing in admin templates.".format(
54-
_ESSENTIAL_ICON_SIZES))
48+
# Currently, these two icon sizes are hard-coded into the admin and admin templates
49+
FILER_TABLE_ICON_SIZE = getattr(settings, "FILER_TABLE_ICON_SIZE", 40)
50+
FILER_THUMBNAIL_ICON_SIZE = getattr(settings, "FILER_THUMBNAIL_ICON_SIZE", 120)
51+
DEFERRED_THUMBNAIL_SIZES = (
52+
FILER_TABLE_ICON_SIZE,
53+
2 * FILER_TABLE_ICON_SIZE,
54+
FILER_THUMBNAIL_ICON_SIZE,
55+
2 * FILER_THUMBNAIL_ICON_SIZE,
56+
)
57+
5558

5659
# This is an ordered iterable that describes a list of
5760
# classes that I should check for when adding files
@@ -283,7 +286,6 @@ def update_server_settings(settings, defaults, s, t):
283286
},
284287
}
285288

286-
DEFERRED_THUMBNAIL_SIZES = (40, 80, 160)
287289
IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.webp']
288290
IMAGE_MIME_TYPES = ['gif', 'jpeg', 'png', 'x-png', 'svg+xml', 'webp']
289291

@@ -322,3 +324,7 @@ def update_server_settings(settings, defaults, s, t):
322324
except (ModuleNotFoundError, ImportError):
323325
# Import error? No django CMS used: stay with own icons
324326
pass
327+
328+
329+
# SVG are their own thumbnails if their size is below this limit
330+
FILER_MAX_SVG_THUMBNAIL_SIZE = getattr(settings, "FILER_MAX_SVG_THUMBNAIL_SIZE", 1024 * 1024) # 1MB default

filer/static/filer/css/admin_filer.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

filer/static/filer/css/maps/admin_filer.css.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)