-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #557 from dandi/dashboard
Add rudimentary admin-only dashboard
- Loading branch information
Showing
3 changed files
with
171 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
from django.core.exceptions import PermissionDenied | ||
from django.db.models import Exists, OuterRef, Q | ||
from django.views.generic.base import TemplateView | ||
|
||
from dandiapi.api.models import Asset, AssetBlob, Upload, Version | ||
|
||
|
||
class DashboardView(TemplateView): | ||
template_name = 'dashboard/index.html' | ||
|
||
def get_context_data(self, **kwargs): | ||
if not self.request.user.is_superuser: | ||
raise PermissionDenied() | ||
context = super().get_context_data(**kwargs) | ||
context['orphaned_asset_count'] = self._orphaned_asset_count() | ||
context['orphaned_asset_blob_count'] = self._orphaned_asset_blob_count() | ||
non_valid_assets = self._non_valid_assets() | ||
context['non_valid_asset_count'] = non_valid_assets.count() | ||
context['non_valid_assets'] = non_valid_assets[:10] | ||
uploads = self._uploads() | ||
context['upload_count'] = uploads.count() | ||
context['uploads'] = uploads[:10] | ||
|
||
return context | ||
|
||
def _orphaned_asset_count(self): | ||
return ( | ||
Asset.objects.annotate( | ||
has_version=Exists(Version.objects.filter(assets=OuterRef('id'))) | ||
) | ||
.filter(has_version=False) | ||
.count() | ||
) | ||
|
||
def _orphaned_asset_blob_count(self): | ||
return ( | ||
AssetBlob.objects.annotate( | ||
has_asset=Exists(Asset.objects.filter(blob_id=OuterRef('id'))) | ||
) | ||
.filter(has_asset=False) | ||
.count() | ||
) | ||
|
||
def _non_valid_assets(self): | ||
return ( | ||
Asset.objects.annotate( | ||
has_version=Exists(Version.objects.filter(assets=OuterRef('id'))) | ||
) | ||
.filter(has_version=True) | ||
.filter(~Q(status=Asset.Status.VALID)) | ||
) | ||
|
||
def _uploads(self): | ||
return Upload.objects.annotate() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
{% extends "admin/base.html" %} | ||
|
||
{% block title %} Data Dashboard {% endblock %} | ||
|
||
{% block branding %} | ||
<h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></h1> | ||
{% endblock %} | ||
|
||
{% block nav-global %}{% endblock %} | ||
|
||
{% block content %} | ||
<div id="content-main"> | ||
<div> | ||
<h1>Orphaned Assets</h1> | ||
<p>There are currently {{ orphaned_asset_count }} Assets with no associated Versions.</p> | ||
{% if orphaned_asset_count %} | ||
<p>They can be cleaned up with the collect_garbage script.</p> | ||
{% endif %} | ||
</div> | ||
|
||
<div> | ||
<h1>Orphaned AssetBlobs</h1> | ||
<p>There are currently {{ orphaned_asset_blob_count }} AssetBlobs with no associated Assets.</p> | ||
{% if orphaned_asset_blob_count %} | ||
<p>They can be cleaned up with the collect_garbage script.</p> | ||
{% endif %} | ||
</div> | ||
|
||
<div> | ||
<h1>Orphaned Uploads</h1> | ||
<p>There are currently {{ upload_count }} Uploads.</p> | ||
{% if uploads %} | ||
<p>They may simply be very recent and currently uploading, or they might be abandoned.</p> | ||
<table> | ||
<caption> | ||
Some Uploads | ||
</caption> | ||
<thead> | ||
<tr> | ||
<td>ID</td> | ||
<td>Upload ID</td> | ||
<td>Size (reported)</td> | ||
<td>Size (actual)</td> | ||
<td>ETag (reported)</td> | ||
<td>ETag (actual)</td> | ||
<td>Created</td> | ||
<td>Modified</td> | ||
</tr> | ||
</thead> | ||
{% for upload in uploads %} | ||
<tr> | ||
<td>{{ upload.id }}</td> | ||
<td>{{ upload.upload_id }}</td> | ||
<td>{{ upload.size }}</td> | ||
<td>{% if upload.object_key_exists %} {{ upload.actual_size }} {% else %} Doesn't exist {% endif %}</td> | ||
<td>{{ upload.etag }}</td> | ||
<td>{% if upload.object_key_exists %} {{ upload.actual_etag }} {% else %} Doesn't exist {% endif %}</td> | ||
<td>{{ upload.created }}</td> | ||
<td>{{ upload.modified }}</td> | ||
</tr> | ||
{% endfor %} | ||
</table> | ||
{% endif %} | ||
</div> | ||
|
||
<div> | ||
<h1>Non-valid Assets</h1> | ||
<p>There are currently {{ non_valid_asset_count }} Assets that are not valid.</p> | ||
{% if non_valid_assets %} | ||
<table> | ||
<caption> | ||
Some Assets that are not valid | ||
</caption> | ||
<thead> | ||
<tr> | ||
<td>ID</td> | ||
<td>Asset ID</td> | ||
<td>Path</td> | ||
<td>Status</td> | ||
<td>Validation Errors</td> | ||
<td>Metadata</td> | ||
<td>Blob ID</td> | ||
<td>Size</td> | ||
<td>SHA256</td> | ||
<td>Versions</td> | ||
<td>Created</td> | ||
<td>Modified</td> | ||
</tr> | ||
</thead> | ||
{% for asset in non_valid_assets %} | ||
<tr> | ||
<td>{{ asset.id }}</td> | ||
<td>{{ asset.asset_id }}</td> | ||
<td>{{ asset.path }}</td> | ||
<td>{{ asset.status }}</td> | ||
<td>{{ asset.validation_errors }}</td> | ||
<td>{{ asset.metadata }}</td> | ||
<td>{{ asset.blob.blob_id }}</td> | ||
<td>{{ asset.size }}</td> | ||
<td>{{ asset.blob.sha256 }}</td> | ||
<td> | ||
{% for version in asset.versions.all %} | ||
{{ version.dandiset.identifier }}/{{ version.version }}, | ||
{% endfor %} | ||
</td> | ||
<td>{{ asset.created }}</td> | ||
<td>{{ asset.modified }}</td> | ||
</tr> | ||
{% endfor %} | ||
</table> | ||
{% endif %} | ||
</div> | ||
|
||
</div> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters