let people view open access series
This commit is contained in:
+2
-1
@@ -2,11 +2,12 @@ from django.core.exceptions import PermissionDenied
|
|||||||
from .models import Case, CaseCollection, Series
|
from .models import Case, CaseCollection, Series
|
||||||
|
|
||||||
|
|
||||||
def user_is_author_or_atlas_series_checker_or_atlas_marker(function):
|
def user_is_author_or_atlas_series_checker_or_atlas_marker_or_open_access(function):
|
||||||
def wrap(request, *args, **kwargs):
|
def wrap(request, *args, **kwargs):
|
||||||
series = Series.objects.get(pk=kwargs["pk"])
|
series = Series.objects.get(pk=kwargs["pk"])
|
||||||
if (
|
if (
|
||||||
request.user in series.get_author_objects()
|
request.user in series.get_author_objects()
|
||||||
|
or series.open_access
|
||||||
or request.user.groups.filter(name="atlas_editor").exists()
|
or request.user.groups.filter(name="atlas_editor").exists()
|
||||||
or request.user.groups.filter(name="atlas_marker").exists()
|
or request.user.groups.filter(name="atlas_marker").exists()
|
||||||
or request.user.is_superuser
|
or request.user.is_superuser
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
{% block navigation%}
|
{% block navigation%}
|
||||||
|
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
{% include 'atlas/series_headers.html' %}
|
{% if can_edit %}
|
||||||
|
{% include 'atlas/series_headers.html' %}
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|||||||
@@ -16,20 +16,24 @@
|
|||||||
<div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ image_url_array_and_count.0 }}" data-annotations=''>
|
<div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ image_url_array_and_count.0 }}" data-annotations=''>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if editing_finding < 1 %}
|
{% if can_edit %}
|
||||||
<button id="add-finding-button">Add finding</button>
|
{% if editing_finding < 1 %}
|
||||||
{% endif %}
|
<button id="add-finding-button">Add finding</button>
|
||||||
<button id="reset-viewport-button">Reset viewport</button>
|
{% endif %}
|
||||||
<div id="finding-form">
|
<button id="reset-viewport-button">Reset viewport</button>
|
||||||
<div class="hide" id="hidden-form">
|
<div id="finding-form">
|
||||||
<form method="post" id="series_finding_form">
|
<div class="hide" id="hidden-form">
|
||||||
{% csrf_token %}
|
<form method="post" id="series_finding_form">
|
||||||
{{series_finding_form|crispy}}
|
{% csrf_token %}
|
||||||
<input type="submit" value="Submit">
|
{{series_finding_form|crispy}}
|
||||||
<button id="cancel-add-finding-button">Cancel</button>
|
<input type="submit" value="Submit">
|
||||||
</form>
|
<button id="cancel-add-finding-button">Cancel</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% else %}
|
||||||
|
<button id="reset-viewport-button">Reset viewport</button>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<details open>
|
<details open>
|
||||||
<summary>Findings</summary>
|
<summary>Findings</summary>
|
||||||
@@ -47,43 +51,46 @@
|
|||||||
Structure(s): {% for s in finding.structures.all %}{{s.get_link}}{% endfor %}<br />
|
Structure(s): {% for s in finding.structures.all %}{{s.get_link}}{% endfor %}<br />
|
||||||
Condition(s): {% for s in finding.conditions.all %}{{s.get_link}}{% endfor %}<br />
|
Condition(s): {% for s in finding.conditions.all %}{{s.get_link}}{% endfor %}<br />
|
||||||
Description: {{finding.description}}<br />
|
Description: {{finding.description}}<br />
|
||||||
|
|
||||||
{% if request.user.is_superuser %}
|
{% if request.user.is_superuser %}
|
||||||
<span _="on click toggle .hidden on next .extra-details">+</span>
|
<span _="on click toggle .hidden on next .extra-details">+</span>
|
||||||
<div class="hidden extra-details">
|
<div class="hidden extra-details">
|
||||||
<h4>Annotation JSON</h4>
|
<h4>Annotation JSON</h4>
|
||||||
<pre>{{finding.annotation_json}}</pre>
|
<pre>{{finding.annotation_json}}</pre>
|
||||||
<h4>Viewport JSON</h4>
|
<h4>Viewport JSON</h4>
|
||||||
<pre>{{finding.viewport_json}}</pre>
|
<pre>{{finding.viewport_json}}</pre>
|
||||||
<h4>Image ID</h4>
|
<h4>Image ID</h4>
|
||||||
<pre>{{finding.current_image_id_index}}</pre>
|
<pre>{{finding.current_image_id_index}}</pre>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
<a href="{% url 'atlas:series_edit_finding' pk=series.pk finding_pk=finding.pk %}" class="edit-finding-link">Edit</a>
|
{% if can_edit %}
|
||||||
|
<a href="{% url 'atlas:series_edit_finding' pk=series.pk finding_pk=finding.pk %}" class="edit-finding-link">Edit</a>
|
||||||
|
<a href="{% url 'atlas:delete_finding' pk=finding.pk %}" class="delete-finding-link">Delete</a>
|
||||||
<a href="{% url 'atlas:delete_finding' pk=finding.pk %}" class="delete-finding-link">Delete</a>
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</details>
|
</details>
|
||||||
<details>
|
{% if can_edit %}
|
||||||
<summary>Truncate series</summary>
|
<details>
|
||||||
<p>
|
<summary>Truncate series</summary>
|
||||||
This will limit the series to the selected bounds (the rest of the images will be deleted). This is useful when you have a large volume of which only a small area is relevant to the case. NOTE: once deleted the images cannot be recovered on the site (they would have to be reuploaded if required). Make sure your images are shown in the correct order above and use test the test truncate button first.
|
<p>
|
||||||
</p>
|
This will limit the series to the selected bounds (the rest of the images will be deleted). This is useful when you have a large volume of which only a small area is relevant to the case. NOTE: once deleted the images cannot be recovered on the site (they would have to be reuploaded if required). Make sure your images are shown in the correct order above and use test the test truncate button first.
|
||||||
Start <input id="lower-truncation-bound-input" type="number" value="1"> <button id="set-lower-truncation-bound-button">Set</button><br/>
|
</p>
|
||||||
End <input id="upper-truncation-bound-input"type="number" value="{{image_url_array_and_count.1}}"> <button id="set-upper-truncation-bound-button">Set</button><br/>
|
Start <input id="lower-truncation-bound-input" type="number" value="1"> <button id="set-lower-truncation-bound-button">Set</button><br/>
|
||||||
<button id="truncate-test-button">Test truncate</button>
|
End <input id="upper-truncation-bound-input"type="number" value="{{image_url_array_and_count.1}}"> <button id="set-upper-truncation-bound-button">Set</button><br/>
|
||||||
<button id="truncate-button">Trucate series</button>
|
<button id="truncate-test-button">Test truncate</button>
|
||||||
<div id="truncate-output"></div>
|
<button id="truncate-button">Trucate series</button>
|
||||||
|
<div id="truncate-output"></div>
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
{% endif %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|
||||||
|
|
||||||
<div>Author: {{ series.get_author_display }}</div>
|
<div>Author: {{ series.get_author_display }}</div>
|
||||||
|
{% if can_edit %}
|
||||||
<details>
|
<details>
|
||||||
<summary>Series info</summary>
|
<summary>Series info</summary>
|
||||||
<div>
|
<div>
|
||||||
@@ -105,25 +112,25 @@
|
|||||||
Image details
|
Image details
|
||||||
</summary>
|
</summary>
|
||||||
<form hx-post="{% url 'atlas:image_diff' %}"
|
<form hx-post="{% url 'atlas:image_diff' %}"
|
||||||
hx-target="#temp"
|
hx-target="#temp"
|
||||||
>
|
>
|
||||||
{% for image in series.get_images %}
|
{% for image in series.get_images %}
|
||||||
[{{ image.id }}] <a href='{% url "atlas:series_image_dicom" image.pk %}'>{{image.image.url}}</a>, pos: {{image.position}}, {{image.upload_filename}}
|
[{{ image.id }}] <a href='{% url "atlas:series_image_dicom" image.pk %}'>{{image.image.url}}</a>, pos: {{image.position}}, {{image.upload_filename}}
|
||||||
|
|
||||||
|
|
||||||
{% if image.image %}
|
{% if image.image %}
|
||||||
[{{image.get_file_size|filesizeformat}}]
|
[{{image.get_file_size|filesizeformat}}]
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{{image.image_md5_hash}} ({{image.is_dicom}}) {{image.image_blake3_hash}}
|
{{image.image_md5_hash}} ({{image.is_dicom}}) {{image.image_blake3_hash}}
|
||||||
|
|
||||||
<input type="checkbox" name="image-id" value="{{image.id}}">
|
<input type="checkbox" name="image-id" value="{{image.id}}">
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
{% comment %} {{image.get_dicom_info|safe}}<br /> {% endcomment %}
|
{% comment %} {{image.get_dicom_info|safe}}<br /> {% endcomment %}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<button>Diff files</button>
|
<button>Diff files</button>
|
||||||
</form>
|
</form>
|
||||||
<span id="temp"></span>
|
<span id="temp"></span>
|
||||||
</details>
|
</details>
|
||||||
@@ -131,21 +138,22 @@
|
|||||||
<p>Total image size: {{series.get_total_image_size|filesizeformat}}</p>
|
<p>Total image size: {{series.get_total_image_size|filesizeformat}}</p>
|
||||||
<p><a href="{% url 'atlas:series_download' pk=series.pk %}">Download images</a></p>
|
<p><a href="{% url 'atlas:series_download' pk=series.pk %}">Download images</a></p>
|
||||||
</details>
|
</details>
|
||||||
<span id="diff-controls">show <span id="diff-show-all" _="on click
|
<span id="diff-controls">show <span id="diff-show-all" _="on click
|
||||||
log '1'
|
log '1'
|
||||||
for row in .diff.rows
|
for row in .diff.rows
|
||||||
show row
|
show row
|
||||||
end">all</span> <span id="diff-show-diff" _="
|
end">all</span> <span id="diff-show-diff" _="
|
||||||
on click
|
on click
|
||||||
log 'go'
|
log 'go'
|
||||||
for row in <.diff tr/>
|
for row in <.diff tr/>
|
||||||
log row.children[0].innerHTML
|
log row.children[0].innerHTML
|
||||||
if row.children[0].innerHTML is empty
|
if row.children[0].innerHTML is empty
|
||||||
hide row
|
hide row
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
">diff</span></span>
|
">diff</span></span>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
|||||||
@@ -297,6 +297,7 @@ urlpatterns = [
|
|||||||
),
|
),
|
||||||
path("structure/create", views.StructureCreate.as_view(), name="structure_create"),
|
path("structure/create", views.StructureCreate.as_view(), name="structure_create"),
|
||||||
path("series/<int:pk>/thumbnail", views.series_thumbnail, name="series_thumbnail"),
|
path("series/<int:pk>/thumbnail", views.series_thumbnail, name="series_thumbnail"),
|
||||||
|
# TODO: case context series viewing (so that we can view series in the context of a case)
|
||||||
path("series/<int:pk>", views.series_detail, name="series_detail"),
|
path("series/<int:pk>", views.series_detail, name="series_detail"),
|
||||||
path("series/<int:pk>/authors", views.SeriesAuthorUpdate.as_view(), name="series_authors"),
|
path("series/<int:pk>/authors", views.SeriesAuthorUpdate.as_view(), name="series_authors"),
|
||||||
path("series/", views.SeriesView.as_view(), name="series_view"),
|
path("series/", views.SeriesView.as_view(), name="series_view"),
|
||||||
|
|||||||
+6
-3
@@ -121,7 +121,7 @@ from autocomplete import HTMXAutoComplete
|
|||||||
from .decorators import (
|
from .decorators import (
|
||||||
user_is_author_or_atlas_editor,
|
user_is_author_or_atlas_editor,
|
||||||
user_has_case_view_access,
|
user_has_case_view_access,
|
||||||
user_is_author_or_atlas_series_checker_or_atlas_marker,
|
user_is_author_or_atlas_series_checker_or_atlas_marker_or_open_access,
|
||||||
user_is_atlas_editor,
|
user_is_atlas_editor,
|
||||||
user_is_author_or_atlas_series_checker,
|
user_is_author_or_atlas_series_checker,
|
||||||
user_is_atlas_marker,
|
user_is_atlas_marker,
|
||||||
@@ -198,7 +198,7 @@ def case_detail(request, pk):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@user_is_author_or_atlas_series_checker_or_atlas_marker
|
@user_is_author_or_atlas_series_checker_or_atlas_marker_or_open_access
|
||||||
def series_thumbnail(request, pk, finding_pk=None):
|
def series_thumbnail(request, pk, finding_pk=None):
|
||||||
series = get_object_or_404(Series, pk=pk)
|
series = get_object_or_404(Series, pk=pk)
|
||||||
|
|
||||||
@@ -208,10 +208,12 @@ def series_thumbnail(request, pk, finding_pk=None):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@user_is_author_or_atlas_series_checker_or_atlas_marker
|
@user_is_author_or_atlas_series_checker_or_atlas_marker_or_open_access
|
||||||
def series_detail(request, pk, finding_pk=None):
|
def series_detail(request, pk, finding_pk=None):
|
||||||
series = get_object_or_404(Series, pk=pk)
|
series = get_object_or_404(Series, pk=pk)
|
||||||
|
|
||||||
|
can_edit = series.check_user_can_edit(request.user)
|
||||||
|
|
||||||
editing_finding = -1
|
editing_finding = -1
|
||||||
if finding_pk is not None:
|
if finding_pk is not None:
|
||||||
finding = get_object_or_404(SeriesFinding, pk=finding_pk)
|
finding = get_object_or_404(SeriesFinding, pk=finding_pk)
|
||||||
@@ -228,6 +230,7 @@ def series_detail(request, pk, finding_pk=None):
|
|||||||
"series": series,
|
"series": series,
|
||||||
"series_finding_form": series_finding_form,
|
"series_finding_form": series_finding_form,
|
||||||
"editing_finding": editing_finding,
|
"editing_finding": editing_finding,
|
||||||
|
"can_edit": can_edit,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user