From b9a66da833c02fc69d7347f1adc0f0122ddf074d Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 8 Apr 2026 22:54:42 +1000 Subject: [PATCH] Fix storage helpers (#11697) * Fix storage helpers - Remove os.path reliance - Move to standard django accessors * Refactor rebuild_thumbnails --- src/backend/InvenTree/InvenTree/helpers.py | 15 ++++++--------- .../management/commands/rebuild_thumbnails.py | 5 ++--- src/backend/InvenTree/InvenTree/tests.py | 5 ++++- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/backend/InvenTree/InvenTree/helpers.py b/src/backend/InvenTree/InvenTree/helpers.py index 101335f6f8..bd358a9fe6 100644 --- a/src/backend/InvenTree/InvenTree/helpers.py +++ b/src/backend/InvenTree/InvenTree/helpers.py @@ -8,6 +8,7 @@ import json import os.path import re from decimal import Decimal, InvalidOperation +from pathlib import Path from typing import Optional, TypeVar from wsgiref.util import FileWrapper from zoneinfo import ZoneInfo, ZoneInfoNotFoundError @@ -35,9 +36,6 @@ from InvenTree.sanitizer import ( DEFAULT_TAGS, ) -from .setting.storages import StorageBackends -from .settings import MEDIA_URL, STATIC_URL - logger = structlog.get_logger('inventree') INT_CLIP_MAX = 0x7FFFFFFF @@ -189,9 +187,8 @@ def getMediaUrl( ) if name is not None: file = regenerate_imagefile(file, name) - if settings.STORAGE_TARGET == StorageBackends.S3: - return str(file.url) - return os.path.join(MEDIA_URL, str(file.url)) + + return default_storage.url(file.name) def regenerate_imagefile(_file, _name: str): @@ -229,7 +226,7 @@ def image2name(img_obj: StdImageField, do_preview: bool, do_thumbnail: bool): def getStaticUrl(filename): """Return the qualified access path for the given file, under the static media directory.""" - return os.path.join(STATIC_URL, str(filename)) + return StaticFilesStorage().url(filename) def TestIfImage(img) -> bool: @@ -261,8 +258,8 @@ def getBlankThumbnail(): def checkStaticFile(*args) -> bool: """Check if a file exists in the static storage.""" static_storage = StaticFilesStorage() - fn = os.path.join(*args) - return static_storage.exists(fn) + fn = Path(*args) + return static_storage.exists(str(fn)) def getLogoImage(as_file=False, custom=True): diff --git a/src/backend/InvenTree/InvenTree/management/commands/rebuild_thumbnails.py b/src/backend/InvenTree/InvenTree/management/commands/rebuild_thumbnails.py index d4b133d5ab..3025f37eb6 100644 --- a/src/backend/InvenTree/InvenTree/management/commands/rebuild_thumbnails.py +++ b/src/backend/InvenTree/InvenTree/management/commands/rebuild_thumbnails.py @@ -3,8 +3,7 @@ - May be required after importing a new dataset, for example """ -import os - +from django.core.files.storage import default_storage from django.core.management.base import BaseCommand from django.db.utils import OperationalError, ProgrammingError @@ -35,7 +34,7 @@ class Command(BaseCommand): img_paths.append(x.path) if len(img_paths) > 0: - if all(os.path.exists(path) for path in img_paths): + if all(default_storage.exists(p) for p in img_paths): # All images exist - skip further work return diff --git a/src/backend/InvenTree/InvenTree/tests.py b/src/backend/InvenTree/InvenTree/tests.py index 7a97997b42..5a303d264d 100644 --- a/src/backend/InvenTree/InvenTree/tests.py +++ b/src/backend/InvenTree/InvenTree/tests.py @@ -692,13 +692,16 @@ class TestHelpers(TestCase): self.assertFalse(helpers.isNull(s)) def testStaticUrl(self): - """Test static url helpers.""" + """Test static URL helpers.""" self.assertEqual(helpers.getStaticUrl('test.jpg'), '/static/test.jpg') self.assertEqual(helpers.getBlankImage(), '/static/img/blank_image.png') self.assertEqual( helpers.getBlankThumbnail(), '/static/img/blank_image.thumbnail.png' ) + self.assertFalse(helpers.checkStaticFile('dummy', 'dir', 'test.jpg')) + self.assertTrue(helpers.checkStaticFile('img', 'blank_image.png')) + def testMediaUrl(self): """Test getMediaUrl.""" # Str should not work