diff --git a/gallery/cache.py b/gallery/cache.py index 3b2d824..3a6adb2 100644 --- a/gallery/cache.py +++ b/gallery/cache.py @@ -7,3 +7,20 @@ def cached_or_set(key, timeout, func): value = func() cache.set(key, value, timeout) return value + + +def cached_or_set_locked(key, timeout, func): + value = cache.get(key) + if value is None: + if cache.add(f"{key}:lock", True, 30): # 30s lukko + value = func() + cache.set(key, value, timeout) + cache.delete(f"{key}:lock") + else: + import time + for _ in range(10): # max 1s odotus + value = cache.get(key) + if value is not None: + break + time.sleep(0.1) + return value diff --git a/gallery/templates/gallery/about.html b/gallery/templates/gallery/about.html index be5d1ca..e252142 100644 --- a/gallery/templates/gallery/about.html +++ b/gallery/templates/gallery/about.html @@ -45,7 +45,7 @@ {{ counts.2 }}  {% blocktrans count photo_count=counts.2 %}photo{% plural %}photos{% endblocktrans %} - + ( {{ counts.3 }} GB )

diff --git a/gallery/templatetags/gallery_stats.py b/gallery/templatetags/gallery_stats.py index aba418c..4dc292c 100644 --- a/gallery/templatetags/gallery_stats.py +++ b/gallery/templatetags/gallery_stats.py @@ -2,8 +2,9 @@ from django import template from django.core.cache import cache from config.cache_durations import * -from gallery.cache import cached_or_set +from gallery.cache import cached_or_set_locked from gallery.models import Album, Photo +from gallery.utils import get_media_size_gb register = template.Library() @@ -14,12 +15,13 @@ def gallery_stats(): Returns a tuple with (total albums, public albums, total photos). Result is cached for GALLERY_STATS_DURATION. """ - return cached_or_set( + return cached_or_set_locked( "gallery_stats", GALLERY_STATS_DURATION, lambda: ( Album.objects.count(), Album.objects.filter(is_public=True).count(), - Photo.objects.count() + Photo.objects.count(), + get_media_size_gb() ) ) diff --git a/gallery/utils.py b/gallery/utils.py index 4ff9f1f..14a7bc6 100644 --- a/gallery/utils.py +++ b/gallery/utils.py @@ -1,9 +1,23 @@ +import os from urllib.parse import urlencode, urlparse, urlunparse from django.conf import settings from django.urls import reverse +def get_media_size_gb(): + total_size = 0 + media_root = settings.MEDIA_ROOT + for dirpath, dirnames, filenames in os.walk(media_root): + for f in filenames: + fp = os.path.join(dirpath, f) + try: + total_size += os.path.getsize(fp) + except OSError: + pass + return round(total_size / (1024 ** 3), 2) # GB, kahden desimaalin tarkkuudella + + def build_canonical_url(request, base_url=None, params=None): if base_url is None: