Skip to content

Commit

Permalink
Merge pull request #110 from DeepMicroscopy/storage
Browse files Browse the repository at this point in the history
Added admin menu with overview for storage / disk usage
  • Loading branch information
maubreville authored Apr 28, 2024
2 parents b9e892d + 9400889 commit ec50242
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 0 deletions.
75 changes: 75 additions & 0 deletions exact/exact/administration/templates/administration/storage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{% extends 'base/base.html' %}
{% load i18n %}
{% load static %}
{% load widget_tweaks %}
{% block taggerimports %}

<script type="text/javascript" src="{% static 'scripts/jquery-3.2.1.min.js' %}"></script>
<script type="text/javascript" src="{% static 'scripts/bootstrap.min.js' %}"></script>

{% endblock taggerimports %}
{% block additional_js %}
<script type="text/javascript" src="{% static 'scripts/plugins_products.js' %}"></script>
<script type="text/javascript" src="{% static 'scripts/notify.min.js' %}"></script>
<script>
$(document).ready(function() {
// Collapse all groups by default (except the first one, if desired)
$('.table-group:not(:first-child)').collapse('hide');

// Add a click event listener to toggle headers
$('.group-header').click(function() {
$(this).siblings('tbody').collapse('toggle');
});
});
</script>
{% endblock additional_js %}


{% block bodyblock %}
{% csrf_token %}
<div class="container-fluid h-100">
<div class="row justify-content-center h-100">
<div class="col-8">
<div class="card">
<div class="card-header">
<h3>
Storage overview
</h3>
</div>
<div style="text-align: left;">
Click on the team to see details.
</div>

<div class="card-body">
<div class="col-md-12">
<table class="table">
{% for team in teams %}
<thead data-toggle="collapse" data-target="#group{{ team.id }}">
<tr class="table-primary"><th colspan=2>Team {{ team.name }}</th><th style="text-align:right"> total: {{ team.storage_disk }}</th></tr>
</thead>
<tbody id="group{{ team.id }}" class="collapse">
<tr><th style="width:20%">Imageset ID</th><th style="width:60%">Name</th><th style="width:20%;text-align:right">Storage (on disk)</th></tr>
{% for imageset in team.imagesets %}
<tr><td>{{ imageset.id }}</td><td style="text-align: left;">
{{ imageset.name }}
</td><td style="text-align:right">{{ imageset.storage_disk }}</td>
</tr>
{% endfor %}
</tbody>

{% endfor %}
</table>
</div>
</div>
</div>
<div class="card text-white bg-primary mb-3" style="width: 18rem; float: right">
Total size: {{ total_storage_gb }}
</div>
<div class="card text-white bg-secondary mb-3" style="width: 18rem; float: right">
Free space: {{ total_free_gb }}
</div>

</div>
</div>
</div>
{% endblock %}
1 change: 1 addition & 0 deletions exact/exact/administration/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand Down
64 changes: 64 additions & 0 deletions exact/exact/administration/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -24,6 +25,9 @@
HTTP_403_FORBIDDEN
from django.conf import settings
import csv
import os
import shutil

def logs(request):

log=[]
Expand Down Expand Up @@ -174,6 +178,66 @@ 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 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
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
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'])
def add_plugin_product(request) -> Response:
print('Running add product with:',request.data)
Expand Down
1 change: 1 addition & 0 deletions exact/exact/base/templates/base/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
{% if show_processing_panel %}
<a class="dropdown-item" href="{% url 'administration:plugins' %}">Plugins</a>
{% endif %}
<a class="dropdown-item" href="{% url 'administration:storage' %}">Storage</a>
</div>
</li>
{% if my_teams %}
Expand Down

0 comments on commit ec50242

Please sign in to comment.