From 3787c1281b437902f8e27fcfd9306e6b90fb370d Mon Sep 17 00:00:00 2001 From: Marc Aubreville Date: Sun, 28 Apr 2024 20:52:05 +0200 Subject: [PATCH 1/4] Added storage overview --- .../templates/administration/storage.html | 66 +++++++++++++++++++ exact/exact/administration/urls.py | 1 + exact/exact/administration/views.py | 38 +++++++++++ exact/exact/base/templates/base/base.html | 1 + 4 files changed, 106 insertions(+) create mode 100644 exact/exact/administration/templates/administration/storage.html diff --git a/exact/exact/administration/templates/administration/storage.html b/exact/exact/administration/templates/administration/storage.html new file mode 100644 index 00000000..9e384006 --- /dev/null +++ b/exact/exact/administration/templates/administration/storage.html @@ -0,0 +1,66 @@ +{% extends 'base/base.html' %} +{% load i18n %} +{% load static %} +{% load widget_tweaks %} +{% block taggerimports %} + + + + +{% endblock taggerimports %} +{% block additional_js %} + + + +{% endblock additional_js %} + + +{% block bodyblock %} +{% csrf_token %} +
+
+
+
+
+

+ Storage overview +

+
+
+
+ + {% for team in teams %} + + + + + + {% for imageset in team.imagesets %} + + + + + {% endfor %} + + + {% endfor %} +
Team {{ team.name }}, total: {{ team.storage_disk }}
Imageset IDNameStorage (on disk)
{{ imageset.id }} + {{ imageset.name }} + {{ imageset.storage_disk }}{{ imageset.storage_files }}
+
+
+
+
+
+
+{% endblock %} diff --git a/exact/exact/administration/urls.py b/exact/exact/administration/urls.py index 128d0998..7c5ed7f3 100644 --- a/exact/exact/administration/urls.py +++ b/exact/exact/administration/urls.py @@ -20,6 +20,7 @@ re_path(r'^products/edit/(\d+)/$', views.edit_product, name='edit_product'), re_path(r'^plugins/list/$', views.plugins, name='plugins'), + re_path(r'^storage/$', views.storage, name='storage'), re_path(r'^api/plugins/product/add/$', views.add_plugin_product, name='add_plugin_product'), re_path(r'^api/plugins/product/delete/$', views.remove_plugin_product, name='remove_plugin_product'), diff --git a/exact/exact/administration/views.py b/exact/exact/administration/views.py index 2e43f9f3..aaa7685e 100644 --- a/exact/exact/administration/views.py +++ b/exact/exact/administration/views.py @@ -15,6 +15,7 @@ from exact.annotations.models import Annotation, AnnotationType from exact.administration.models import Product from exact.users.models import Team +from exact.images.models import ImageSet from exact.administration.serializers import serialize_annotationType, ProductSerializer from rest_framework.decorators import api_view @@ -24,6 +25,7 @@ HTTP_403_FORBIDDEN from django.conf import settings import csv +import os def logs(request): log=[] @@ -174,6 +176,42 @@ def plugins(request): 'teams': teams }) + +def folder_size(path): + """ + Calculates the size of a folder + :param path: path to folder to analyze + :return: size in GB of the folder + """ + size = 0 + for dirpath, dirnames, filenames in os.walk(path): + for f in filenames: + fp = os.path.join(dirpath, f) + if os.path.isfile(fp) and not os.path.islink(fp): + size += os.path.getsize(fp) + return round(size / (1024.0 * 1024.0 * 1024.0), 2) + +def storage(request): + + teams = Team.objects.filter(members=request.user) + #if (request.user.is_superuser): + teams = Team.objects.all() + + for team in teams: + imagesets = ImageSet.objects.filter(team=team).order_by('name') + totalteam = 0 + for imageset in imagesets: + filesize_gb = folder_size(imageset.root_path()) + imageset.storage_disk = '%.2f GB' % filesize_gb + totalteam += filesize_gb + team.storage_disk = '%.2f GB' % totalteam + team.imagesets = imagesets + + + return render(request, 'administration/storage.html', { + 'teams' : teams, + }) + @api_view(['POST']) def add_plugin_product(request) -> Response: print('Running add product with:',request.data) diff --git a/exact/exact/base/templates/base/base.html b/exact/exact/base/templates/base/base.html index 4bd4143b..a1c8567d 100644 --- a/exact/exact/base/templates/base/base.html +++ b/exact/exact/base/templates/base/base.html @@ -79,6 +79,7 @@ {% if show_processing_panel %} Plugins {% endif %} + Storage {% if my_teams %} From f16e837b4ee7927643eb39c55f26e99f281f5cf5 Mon Sep 17 00:00:00 2001 From: Marc Aubreville Date: Sun, 28 Apr 2024 21:13:15 +0200 Subject: [PATCH 2/4] Update to storage (includes now also total and free space) --- .../templates/administration/storage.html | 11 ++++++++ exact/exact/administration/views.py | 28 ++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/exact/exact/administration/templates/administration/storage.html b/exact/exact/administration/templates/administration/storage.html index 9e384006..744e5474 100644 --- a/exact/exact/administration/templates/administration/storage.html +++ b/exact/exact/administration/templates/administration/storage.html @@ -36,6 +36,10 @@

Storage overview

+
+ Click on the team to see details. +
+
@@ -60,6 +64,13 @@

+
+ Total storage is: {{ total_storage_gb }} +
+
+ Free space: {{ total_free_gb }} +
+ diff --git a/exact/exact/administration/views.py b/exact/exact/administration/views.py index aaa7685e..4bc90be6 100644 --- a/exact/exact/administration/views.py +++ b/exact/exact/administration/views.py @@ -26,6 +26,8 @@ from django.conf import settings import csv import os +import shutil + def logs(request): log=[] @@ -191,12 +193,32 @@ def folder_size(path): size += os.path.getsize(fp) return round(size / (1024.0 * 1024.0 * 1024.0), 2) + +def get_estimated_free_space(path): + """ + This function estimates free space on the filesystem using shutil.disk_usage. + + Args: + path: The path to check for free space (e.g., '/') + + Returns: + The estimated free space in bytes as a float, + or None on error. + """ + try: + total, used, free = shutil.disk_usage(path) + return float(free) + except Exception as e: + print(f"Error getting free space: {e}") + return 0 + def storage(request): teams = Team.objects.filter(members=request.user) #if (request.user.is_superuser): teams = Team.objects.all() + total_storage_gb = 0 for team in teams: imagesets = ImageSet.objects.filter(team=team).order_by('name') totalteam = 0 @@ -206,10 +228,14 @@ def storage(request): totalteam += filesize_gb team.storage_disk = '%.2f GB' % totalteam team.imagesets = imagesets - + total_storage_gb += totalteam + + total_free = get_estimated_free_space(settings.IMAGE_PATH) return render(request, 'administration/storage.html', { 'teams' : teams, + 'total_storage_gb' : '%.2f GB' % total_storage_gb, + 'total_free_gb' : '%.2f GB' % (total_free/1024/1024/1024) }) @api_view(['POST']) From ac9460f4316b984e197a635e867ae59ca7141a80 Mon Sep 17 00:00:00 2001 From: Marc Aubreville Date: Sun, 28 Apr 2024 21:17:06 +0200 Subject: [PATCH 3/4] beautified template --- .../administration/templates/administration/storage.html | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/exact/exact/administration/templates/administration/storage.html b/exact/exact/administration/templates/administration/storage.html index 744e5474..49e85a78 100644 --- a/exact/exact/administration/templates/administration/storage.html +++ b/exact/exact/administration/templates/administration/storage.html @@ -45,16 +45,14 @@

{% for team in teams %} - + - + {% for imageset in team.imagesets %} - - + {% endfor %} From 94008896185aa9396d089e7e71a848651bedae51 Mon Sep 17 00:00:00 2001 From: Marc Aubreville Date: Sun, 28 Apr 2024 21:23:54 +0200 Subject: [PATCH 4/4] Fine adjustment of terms. --- .../exact/administration/templates/administration/storage.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exact/exact/administration/templates/administration/storage.html b/exact/exact/administration/templates/administration/storage.html index 49e85a78..950b1267 100644 --- a/exact/exact/administration/templates/administration/storage.html +++ b/exact/exact/administration/templates/administration/storage.html @@ -63,7 +63,7 @@

- Total storage is: {{ total_storage_gb }} + Total size: {{ total_storage_gb }}
Free space: {{ total_free_gb }}

Team {{ team.name }}, total: {{ team.storage_disk }}
Team {{ team.name }} total: {{ team.storage_disk }}
Imageset IDNameStorage (on disk)
Imageset IDNameStorage (on disk)
{{ imageset.id }} {{ imageset.name }} - {{ imageset.storage_disk }}{{ imageset.storage_files }}{{ imageset.storage_disk }}