endoreg-db 0.8.1__py3-none-any.whl → 0.8.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of endoreg-db might be problematic. Click here for more details.

Files changed (37) hide show
  1. endoreg_db/helpers/download_segmentation_model.py +31 -0
  2. endoreg_db/models/media/video/pipe_1.py +13 -1
  3. endoreg_db/serializers/anonymization.py +3 -0
  4. endoreg_db/services/pdf_import.py +0 -30
  5. endoreg_db/services/video_import.py +301 -98
  6. endoreg_db/urls/__init__.py +0 -2
  7. endoreg_db/urls/media.py +201 -4
  8. endoreg_db/urls/report.py +0 -30
  9. endoreg_db/urls/video.py +30 -88
  10. endoreg_db/views/anonymization/validate.py +5 -2
  11. endoreg_db/views/media/__init__.py +38 -2
  12. endoreg_db/views/media/pdf_media.py +1 -1
  13. endoreg_db/views/media/segments.py +71 -0
  14. endoreg_db/views/media/sensitive_metadata.py +314 -0
  15. endoreg_db/views/media/video_segments.py +596 -0
  16. endoreg_db/views/pdf/reimport.py +18 -8
  17. endoreg_db/views/video/__init__.py +0 -8
  18. endoreg_db/views/video/correction.py +26 -26
  19. endoreg_db/views/video/reimport.py +15 -12
  20. endoreg_db/views/video/video_stream.py +168 -50
  21. {endoreg_db-0.8.1.dist-info → endoreg_db-0.8.2.dist-info}/METADATA +2 -2
  22. {endoreg_db-0.8.1.dist-info → endoreg_db-0.8.2.dist-info}/RECORD +34 -33
  23. endoreg_db/urls/pdf.py +0 -0
  24. endoreg_db/urls/sensitive_meta.py +0 -36
  25. endoreg_db/views/video/media/__init__.py +0 -23
  26. /endoreg_db/views/video/{media/task_status.py → task_status.py} +0 -0
  27. /endoreg_db/views/video/{media/video_analyze.py → video_analyze.py} +0 -0
  28. /endoreg_db/views/video/{media/video_apply_mask.py → video_apply_mask.py} +0 -0
  29. /endoreg_db/views/video/{media/video_correction.py → video_correction.py} +0 -0
  30. /endoreg_db/views/video/{media/video_download_processed.py → video_download_processed.py} +0 -0
  31. /endoreg_db/views/video/{media/video_media.py → video_media.py} +0 -0
  32. /endoreg_db/views/video/{media/video_meta.py → video_meta.py} +0 -0
  33. /endoreg_db/views/video/{media/video_processing_history.py → video_processing_history.py} +0 -0
  34. /endoreg_db/views/video/{media/video_remove_frames.py → video_remove_frames.py} +0 -0
  35. /endoreg_db/views/video/{media/video_reprocess.py → video_reprocess.py} +0 -0
  36. {endoreg_db-0.8.1.dist-info → endoreg_db-0.8.2.dist-info}/WHEEL +0 -0
  37. {endoreg_db-0.8.1.dist-info → endoreg_db-0.8.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,314 @@
1
+ # Modern Media Framework: Sensitive Metadata Management
2
+ from rest_framework.decorators import api_view, permission_classes
3
+ from rest_framework.response import Response
4
+ from rest_framework import status
5
+ from django.db import transaction
6
+ from django.db.models import Q
7
+ from django.shortcuts import get_object_or_404
8
+ from endoreg_db.utils.permissions import EnvironmentAwarePermission
9
+ from endoreg_db.models import VideoFile, RawPdfFile, SensitiveMeta
10
+ from endoreg_db.serializers.meta import (
11
+ SensitiveMetaDetailSerializer,
12
+ SensitiveMetaUpdateSerializer,
13
+ )
14
+
15
+ # === VIDEO SENSITIVE METADATA ===
16
+
17
+ @api_view(['GET', 'PATCH'])
18
+ @permission_classes([EnvironmentAwarePermission])
19
+ def video_sensitive_metadata(request, pk):
20
+ """
21
+ GET /api/media/videos/<pk>/sensitive-metadata/
22
+ PATCH /api/media/videos/<pk>/sensitive-metadata/
23
+
24
+ Get or update sensitive metadata for a video.
25
+ Video-scoped: Uses video ID to locate related sensitive metadata.
26
+ """
27
+ video = get_object_or_404(VideoFile, pk=pk)
28
+
29
+ # Get related sensitive metadata
30
+ if not video.sensitive_meta:
31
+ return Response(
32
+ {"error": f"No sensitive metadata found for video {pk}"},
33
+ status=status.HTTP_404_NOT_FOUND
34
+ )
35
+
36
+ sensitive_meta = video.sensitive_meta
37
+
38
+ if request.method == 'GET':
39
+ serializer = SensitiveMetaDetailSerializer(sensitive_meta)
40
+ return Response(serializer.data, status=status.HTTP_200_OK)
41
+
42
+ elif request.method == 'PATCH':
43
+ serializer = SensitiveMetaUpdateSerializer(
44
+ sensitive_meta,
45
+ data=request.data,
46
+ partial=True
47
+ )
48
+
49
+ if serializer.is_valid():
50
+ updated_instance = serializer.save()
51
+ response_serializer = SensitiveMetaDetailSerializer(updated_instance)
52
+
53
+ return Response({
54
+ "message": "Sensitive metadata updated successfully",
55
+ "sensitive_meta": response_serializer.data,
56
+ "video_id": pk
57
+ }, status=status.HTTP_200_OK)
58
+
59
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
60
+
61
+
62
+ @api_view(['POST'])
63
+ @permission_classes([EnvironmentAwarePermission])
64
+ @transaction.atomic
65
+ def video_sensitive_metadata_verify(request, pk):
66
+ """
67
+ POST /api/media/videos/<pk>/sensitive-metadata/verify/
68
+
69
+ Update verification state for video sensitive metadata.
70
+
71
+ Expected payload:
72
+ {
73
+ "dob_verified": true,
74
+ "names_verified": true
75
+ }
76
+ """
77
+ video = get_object_or_404(VideoFile, pk=pk)
78
+
79
+ if not video.sensitive_meta:
80
+ return Response(
81
+ {"error": f"No sensitive metadata found for video {pk}"},
82
+ status=status.HTTP_404_NOT_FOUND
83
+ )
84
+
85
+ sensitive_meta = video.sensitive_meta
86
+
87
+ dob_verified = request.data.get('dob_verified')
88
+ names_verified = request.data.get('names_verified')
89
+
90
+ if dob_verified is None and names_verified is None:
91
+ return Response(
92
+ {"error": "At least one of dob_verified or names_verified must be provided"},
93
+ status=status.HTTP_400_BAD_REQUEST
94
+ )
95
+
96
+ state = sensitive_meta.get_or_create_state()
97
+
98
+ if dob_verified is not None:
99
+ state.dob_verified = dob_verified
100
+ if names_verified is not None:
101
+ state.names_verified = names_verified
102
+
103
+ state.save()
104
+
105
+ response_serializer = SensitiveMetaDetailSerializer(sensitive_meta)
106
+ return Response({
107
+ "message": "Verification state updated successfully",
108
+ "sensitive_meta": response_serializer.data,
109
+ "video_id": pk,
110
+ "state_verified": state.is_verified
111
+ }, status=status.HTTP_200_OK)
112
+
113
+
114
+ # === PDF SENSITIVE METADATA ===
115
+
116
+ @api_view(['GET', 'PATCH'])
117
+ @permission_classes([EnvironmentAwarePermission])
118
+ def pdf_sensitive_metadata(request, pk):
119
+ """
120
+ GET /api/media/pdfs/<pk>/sensitive-metadata/
121
+ PATCH /api/media/pdfs/<pk>/sensitive-metadata/
122
+
123
+ Get or update sensitive metadata for a PDF.
124
+ PDF-scoped: Uses PDF ID to locate related sensitive metadata.
125
+ """
126
+ pdf = get_object_or_404(RawPdfFile, pk=pk)
127
+
128
+ # Get related sensitive metadata
129
+ if not pdf.sensitive_meta:
130
+ return Response(
131
+ {"error": f"No sensitive metadata found for PDF {pk}"},
132
+ status=status.HTTP_404_NOT_FOUND
133
+ )
134
+
135
+ sensitive_meta = pdf.sensitive_meta
136
+
137
+ if request.method == 'GET':
138
+ serializer = SensitiveMetaDetailSerializer(sensitive_meta)
139
+ return Response(serializer.data, status=status.HTTP_200_OK)
140
+
141
+ elif request.method == 'PATCH':
142
+ serializer = SensitiveMetaUpdateSerializer(
143
+ sensitive_meta,
144
+ data=request.data,
145
+ partial=True
146
+ )
147
+
148
+ if serializer.is_valid():
149
+ updated_instance = serializer.save()
150
+ response_serializer = SensitiveMetaDetailSerializer(updated_instance)
151
+
152
+ return Response({
153
+ "message": "Sensitive metadata updated successfully",
154
+ "sensitive_meta": response_serializer.data,
155
+ "pdf_id": pk
156
+ }, status=status.HTTP_200_OK)
157
+
158
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
159
+
160
+
161
+ @api_view(['POST'])
162
+ @permission_classes([EnvironmentAwarePermission])
163
+ @transaction.atomic
164
+ def pdf_sensitive_metadata_verify(request, pk):
165
+ """
166
+ POST /api/media/pdfs/<pk>/sensitive-metadata/verify/
167
+
168
+ Update verification state for PDF sensitive metadata.
169
+
170
+ Expected payload:
171
+ {
172
+ "dob_verified": true,
173
+ "names_verified": true
174
+ }
175
+ """
176
+ pdf = get_object_or_404(RawPdfFile, pk=pk)
177
+
178
+ if not pdf.sensitive_meta:
179
+ return Response(
180
+ {"error": f"No sensitive metadata found for PDF {pk}"},
181
+ status=status.HTTP_404_NOT_FOUND
182
+ )
183
+
184
+ sensitive_meta = pdf.sensitive_meta
185
+
186
+ dob_verified = request.data.get('dob_verified')
187
+ names_verified = request.data.get('names_verified')
188
+
189
+ if dob_verified is None and names_verified is None:
190
+ return Response(
191
+ {"error": "At least one of dob_verified or names_verified must be provided"},
192
+ status=status.HTTP_400_BAD_REQUEST
193
+ )
194
+
195
+ state = sensitive_meta.get_or_create_state()
196
+
197
+ if dob_verified is not None:
198
+ state.dob_verified = dob_verified
199
+ if names_verified is not None:
200
+ state.names_verified = names_verified
201
+
202
+ state.save()
203
+
204
+ response_serializer = SensitiveMetaDetailSerializer(sensitive_meta)
205
+ return Response({
206
+ "message": "Verification state updated successfully",
207
+ "sensitive_meta": response_serializer.data,
208
+ "pdf_id": pk,
209
+ "state_verified": state.is_verified
210
+ }, status=status.HTTP_200_OK)
211
+
212
+
213
+ # === LIST ENDPOINTS (Collection-Level) ===
214
+
215
+ @api_view(['GET'])
216
+ @permission_classes([EnvironmentAwarePermission])
217
+ def sensitive_metadata_list(request):
218
+ """
219
+ GET /api/media/sensitive-metadata/
220
+
221
+ List all sensitive metadata (combined PDFs and Videos).
222
+ Supports filtering by content_type, status, etc.
223
+
224
+ Query parameters:
225
+ - content_type: 'pdf' | 'video' (optional)
226
+ - verified: Filter by verification status
227
+ - ordering: Sort field
228
+ - search: Search in patient names
229
+ """
230
+ from endoreg_db.serializers.meta import SensitiveMetaDetailSerializer
231
+
232
+ # Get all sensitive metadata
233
+ queryset = SensitiveMeta.objects.select_related('state').all()
234
+
235
+ # Filter by content type
236
+ content_type = request.query_params.get('content_type')
237
+ if content_type == 'pdf':
238
+ # Only PDFs - filter by existence of related PDFs
239
+ queryset = queryset.filter(raw_pdf_files__isnull=False).distinct()
240
+ elif content_type == 'video':
241
+ # Only Videos - filter by existence of related video
242
+ queryset = queryset.filter(video_file__isnull=False).distinct()
243
+
244
+ # Filter by verification status
245
+ verified = request.query_params.get('verified')
246
+ if verified is not None:
247
+ verified_bool = verified.lower() in ('true', '1', 'yes')
248
+ queryset = queryset.filter(state__is_verified=verified_bool)
249
+
250
+ # Search in patient names
251
+ search = request.query_params.get('search')
252
+ if search:
253
+ queryset = queryset.filter(
254
+ Q(patient_first_name__icontains=search) |
255
+ Q(patient_last_name__icontains=search)
256
+ )
257
+
258
+ # Ordering
259
+ ordering = request.query_params.get('ordering', '-id')
260
+ queryset = queryset.order_by(ordering)
261
+
262
+ # Pagination
263
+ from rest_framework.pagination import PageNumberPagination
264
+ paginator = PageNumberPagination()
265
+ paginator.page_size = 20
266
+ page = paginator.paginate_queryset(queryset, request)
267
+
268
+ if page is not None:
269
+ serializer = SensitiveMetaDetailSerializer(page, many=True)
270
+ return paginator.get_paginated_response(serializer.data)
271
+
272
+ serializer = SensitiveMetaDetailSerializer(queryset, many=True)
273
+ return Response(serializer.data, status=status.HTTP_200_OK)
274
+
275
+
276
+ @api_view(['GET'])
277
+ @permission_classes([EnvironmentAwarePermission])
278
+ def pdf_sensitive_metadata_list(request):
279
+ """
280
+ GET /api/media/pdfs/sensitive-metadata/
281
+
282
+ List sensitive metadata for PDFs only.
283
+ Replaces legacy /api/pdf/sensitivemeta/list/
284
+ """
285
+ from endoreg_db.serializers.meta import SensitiveMetaDetailSerializer
286
+
287
+ # Get all PDFs with sensitive metadata
288
+ queryset = SensitiveMeta.objects.select_related('state').filter(
289
+ raw_pdf_files__isnull=False
290
+ ).distinct()
291
+
292
+ # Apply filters
293
+ search = request.query_params.get('search')
294
+ if search:
295
+ queryset = queryset.filter(
296
+ Q(patient_first_name__icontains=search) |
297
+ Q(patient_last_name__icontains=search)
298
+ )
299
+
300
+ ordering = request.query_params.get('ordering', '-id')
301
+ queryset = queryset.order_by(ordering)
302
+
303
+ # Pagination
304
+ from rest_framework.pagination import PageNumberPagination
305
+ paginator = PageNumberPagination()
306
+ paginator.page_size = 20
307
+ page = paginator.paginate_queryset(queryset, request)
308
+
309
+ if page is not None:
310
+ serializer = SensitiveMetaDetailSerializer(page, many=True)
311
+ return paginator.get_paginated_response(serializer.data)
312
+
313
+ serializer = SensitiveMetaDetailSerializer(queryset, many=True)
314
+ return Response(serializer.data, status=status.HTTP_200_OK)