endoreg-db 0.8.5.8__py3-none-any.whl → 0.8.5.9__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.
- endoreg_db/serializers/misc/file_overview.py +65 -35
- {endoreg_db-0.8.5.8.dist-info → endoreg_db-0.8.5.9.dist-info}/METADATA +1 -1
- {endoreg_db-0.8.5.8.dist-info → endoreg_db-0.8.5.9.dist-info}/RECORD +5 -5
- {endoreg_db-0.8.5.8.dist-info → endoreg_db-0.8.5.9.dist-info}/WHEEL +0 -0
- {endoreg_db-0.8.5.8.dist-info → endoreg_db-0.8.5.9.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
from rest_framework import serializers
|
|
2
1
|
from typing import TYPE_CHECKING
|
|
3
|
-
|
|
4
|
-
from
|
|
5
|
-
|
|
2
|
+
|
|
3
|
+
from rest_framework import serializers
|
|
4
|
+
|
|
5
|
+
from endoreg_db.models.media import RawPdfFile, VideoFile
|
|
6
|
+
from endoreg_db.models.state.raw_pdf import (
|
|
7
|
+
AnonymizationStatus as PdfAnonymizationStatus,
|
|
8
|
+
)
|
|
9
|
+
from endoreg_db.models.state.video import (
|
|
10
|
+
AnonymizationStatus as VideoAnonymizationStatus,
|
|
11
|
+
)
|
|
6
12
|
|
|
7
13
|
if TYPE_CHECKING:
|
|
8
14
|
pass
|
|
9
15
|
|
|
16
|
+
|
|
10
17
|
class FileOverviewSerializer(serializers.Serializer):
|
|
11
18
|
"""
|
|
12
19
|
Polymorphic "union" serializer – we normalise both model types
|
|
@@ -22,75 +29,81 @@ class FileOverviewSerializer(serializers.Serializer):
|
|
|
22
29
|
annotationStatus = serializers.CharField(read_only=True)
|
|
23
30
|
createdAt = serializers.DateTimeField(read_only=True)
|
|
24
31
|
text = serializers.CharField(required=False, allow_blank=True, read_only=True)
|
|
25
|
-
anonymizedText = serializers.CharField(
|
|
32
|
+
anonymizedText = serializers.CharField(
|
|
33
|
+
required=False, allow_blank=True, read_only=True
|
|
34
|
+
)
|
|
26
35
|
|
|
27
36
|
# --- converting DB objects to that shape -----------------------
|
|
28
37
|
def to_representation(self, instance):
|
|
29
38
|
"""
|
|
30
39
|
Return a unified dictionary representation of either a VideoFile or RawPdfFile instance for front-end use.
|
|
31
|
-
|
|
40
|
+
|
|
32
41
|
For VideoFile instances, extracts and structures metadata such as patient, examination, equipment, and examiner information, and generates an anonymized version of the text by replacing sensitive fields with placeholders. For RawPdfFile instances, extracts text and anonymized text directly and determines statuses based on available fields.
|
|
33
|
-
|
|
42
|
+
|
|
34
43
|
Parameters:
|
|
35
44
|
instance: A VideoFile or RawPdfFile object to be serialized.
|
|
36
|
-
|
|
45
|
+
|
|
37
46
|
Returns:
|
|
38
47
|
dict: A normalized dictionary containing id, filename, mediaType, anonymizationStatus, annotationStatus, createdAt, text, and anonymizedText fields.
|
|
39
|
-
|
|
48
|
+
|
|
40
49
|
Raises:
|
|
41
50
|
TypeError: If the instance is not a VideoFile or RawPdfFile.
|
|
42
51
|
"""
|
|
43
52
|
text = ""
|
|
44
53
|
anonym_text = ""
|
|
45
|
-
|
|
54
|
+
|
|
46
55
|
if isinstance(instance, VideoFile):
|
|
47
56
|
media_type = "video"
|
|
48
57
|
created_at = instance.uploaded_at
|
|
49
58
|
filename = instance.original_file_name or (
|
|
50
|
-
instance.raw_file.name.split("/")[-1]
|
|
59
|
+
instance.raw_file.name.split("/")[-1]
|
|
60
|
+
if instance.raw_file
|
|
61
|
+
else "unknown"
|
|
51
62
|
)
|
|
52
|
-
|
|
63
|
+
|
|
53
64
|
# ------- anonymization status using VideoState model
|
|
54
65
|
vs = instance.state
|
|
55
|
-
anonym_status =
|
|
56
|
-
|
|
66
|
+
anonym_status = (
|
|
67
|
+
vs.anonymization_status if vs else VideoAnonymizationStatus.NOT_STARTED
|
|
68
|
+
)
|
|
69
|
+
|
|
57
70
|
# ------- annotation status (validated label segments)
|
|
58
71
|
if instance.label_video_segments.filter(state__is_validated=True).exists():
|
|
59
72
|
annot_status = "done"
|
|
60
73
|
else:
|
|
61
74
|
annot_status = "not_started"
|
|
62
|
-
|
|
75
|
+
|
|
63
76
|
# ------- Extract text from sensitive_meta for videos
|
|
64
77
|
if instance.sensitive_meta:
|
|
65
78
|
sm = instance.sensitive_meta
|
|
66
79
|
# Create a structured text representation from sensitive meta
|
|
67
80
|
text_parts = []
|
|
68
|
-
|
|
81
|
+
|
|
69
82
|
# Patient information
|
|
70
83
|
if sm.patient_first_name or sm.patient_last_name:
|
|
71
84
|
patient_name = f"{sm.patient_first_name or ''} {sm.patient_last_name or ''}".strip()
|
|
72
85
|
text_parts.append(f"Patient: {patient_name}")
|
|
73
|
-
|
|
86
|
+
|
|
74
87
|
if sm.patient_dob:
|
|
75
88
|
text_parts.append(f"Date of Birth: {sm.patient_dob.date()}")
|
|
76
|
-
|
|
89
|
+
|
|
77
90
|
if sm.patient_gender:
|
|
78
91
|
text_parts.append(f"Gender: {sm.patient_gender}")
|
|
79
|
-
|
|
92
|
+
|
|
80
93
|
# Examination information
|
|
81
94
|
if sm.examination_date:
|
|
82
95
|
text_parts.append(f"Examination Date: {sm.examination_date}")
|
|
83
|
-
|
|
96
|
+
|
|
84
97
|
if sm.center:
|
|
85
98
|
text_parts.append(f"Center: {sm.center.name}")
|
|
86
|
-
|
|
99
|
+
|
|
87
100
|
# Equipment information
|
|
88
101
|
if sm.endoscope_type:
|
|
89
102
|
text_parts.append(f"Endoscope Type: {sm.endoscope_type}")
|
|
90
|
-
|
|
103
|
+
|
|
91
104
|
if sm.endoscope_sn:
|
|
92
105
|
text_parts.append(f"Endoscope SN: {sm.endoscope_sn}")
|
|
93
|
-
|
|
106
|
+
|
|
94
107
|
# Examiner information
|
|
95
108
|
if sm.pk: # Only if saved
|
|
96
109
|
try:
|
|
@@ -100,39 +113,56 @@ class FileOverviewSerializer(serializers.Serializer):
|
|
|
100
113
|
text_parts.append(f"Examiners: {examiner_names}")
|
|
101
114
|
except Exception:
|
|
102
115
|
pass # Ignore examiner lookup errors
|
|
103
|
-
|
|
116
|
+
|
|
104
117
|
text = "\n".join(text_parts)
|
|
105
|
-
|
|
118
|
+
|
|
106
119
|
# Create anonymized version by replacing sensitive data
|
|
107
120
|
anonym_text = text
|
|
108
121
|
if sm.patient_first_name:
|
|
109
|
-
anonym_text = anonym_text.replace(
|
|
122
|
+
anonym_text = anonym_text.replace(
|
|
123
|
+
sm.patient_first_name, "[FIRST_NAME]"
|
|
124
|
+
)
|
|
110
125
|
if sm.patient_last_name:
|
|
111
|
-
anonym_text = anonym_text.replace(
|
|
126
|
+
anonym_text = anonym_text.replace(
|
|
127
|
+
sm.patient_last_name, "[LAST_NAME]"
|
|
128
|
+
)
|
|
112
129
|
if sm.patient_dob:
|
|
113
|
-
anonym_text = anonym_text.replace(
|
|
130
|
+
anonym_text = anonym_text.replace(
|
|
131
|
+
str(sm.patient_dob.date()), "[DOB]"
|
|
132
|
+
)
|
|
114
133
|
if sm.endoscope_sn:
|
|
115
134
|
anonym_text = anonym_text.replace(sm.endoscope_sn, "[ENDOSCOPE_SN]")
|
|
116
|
-
|
|
135
|
+
|
|
117
136
|
# Replace examiner names if available
|
|
118
137
|
if sm.pk:
|
|
119
138
|
try:
|
|
120
139
|
examiners = list(sm.examiners.all())
|
|
121
140
|
for examiner in examiners:
|
|
122
|
-
anonym_text = anonym_text.replace(
|
|
141
|
+
anonym_text = anonym_text.replace(
|
|
142
|
+
str(examiner), "[EXAMINER]"
|
|
143
|
+
)
|
|
123
144
|
except Exception:
|
|
124
145
|
pass
|
|
125
146
|
|
|
126
147
|
elif isinstance(instance, RawPdfFile):
|
|
127
|
-
instance:RawPdfFile
|
|
148
|
+
instance: RawPdfFile
|
|
128
149
|
media_type = "pdf"
|
|
129
150
|
created_at = instance.date_created
|
|
130
151
|
filename = instance.file.name.split("/")[-1] if instance.file else "unknown"
|
|
131
|
-
|
|
132
|
-
|
|
152
|
+
|
|
153
|
+
# ------- anonymization status using RawPdfState model (like VideoFile)
|
|
154
|
+
ps = instance.state
|
|
155
|
+
anonym_status = (
|
|
156
|
+
ps.anonymization_status if ps else PdfAnonymizationStatus.NOT_STARTED
|
|
157
|
+
)
|
|
158
|
+
|
|
133
159
|
# PDF annotation == "sensitive meta validated"
|
|
134
|
-
annot_status =
|
|
135
|
-
|
|
160
|
+
annot_status = (
|
|
161
|
+
"done"
|
|
162
|
+
if getattr(instance.sensitive_meta, "is_verified", False)
|
|
163
|
+
else "not_started"
|
|
164
|
+
)
|
|
165
|
+
|
|
136
166
|
# Extract text content from PDF
|
|
137
167
|
text = instance.text or ""
|
|
138
168
|
anonym_text = instance.anonymized_text or ""
|
|
@@ -559,7 +559,7 @@ endoreg_db/serializers/meta/sensitive_meta_update.py,sha256=qy7cM2MhQUJST9YcEXuy
|
|
|
559
559
|
endoreg_db/serializers/meta/sensitive_meta_verification.py,sha256=gXH2RfJtVPSgnA3Z58FU6kxTZs6vBI14EEZT7lx2NFE,2289
|
|
560
560
|
endoreg_db/serializers/meta/video_meta.py,sha256=g96J4va5_oIg7rbbVqcyBsy8imgmbiHjysuEEtas0cA,1284
|
|
561
561
|
endoreg_db/serializers/misc/__init__.py,sha256=MfG55Bb9sNBajmt-QkTOg1qFNSOEFQ6RWHIA_DVtneE,489
|
|
562
|
-
endoreg_db/serializers/misc/file_overview.py,sha256=
|
|
562
|
+
endoreg_db/serializers/misc/file_overview.py,sha256=ImOTX4a_zjboVyQs2IHBFNqhEfZWDvgcrx1bf2XpL2w,7395
|
|
563
563
|
endoreg_db/serializers/misc/sensitive_patient_data.py,sha256=cewApBYKsk0s9T7CGY_FJmuXAYs3hJV3Ra7oYazKndk,5831
|
|
564
564
|
endoreg_db/serializers/misc/stats.py,sha256=iL8iZseOLeLaoaCDF3MtTQBH3b0yX5ZFkrZbq5MiMGM,1255
|
|
565
565
|
endoreg_db/serializers/misc/translatable_field_mix_in.py,sha256=ZH8ZUE1-No0DLCcIGk445c00jQcX7M6Yldxik-FaGfg,1724
|
|
@@ -789,7 +789,7 @@ endoreg_db/views/video/video_meta.py,sha256=C1wBMTtQb_yzEUrhFGAy2UHEWMk_CbU75WXX
|
|
|
789
789
|
endoreg_db/views/video/video_processing_history.py,sha256=mhFuS8RG5GV8E-lTtuD0qrq-bIpnUFp8vy9aERfC-J8,770
|
|
790
790
|
endoreg_db/views/video/video_remove_frames.py,sha256=2FmvNrSPM0fUXiBxINN6vBUUDCqDlBkNcGR3WsLDgKo,1696
|
|
791
791
|
endoreg_db/views/video/video_stream.py,sha256=kLyuf0ORTmsLeYUQkTQ6iRYqlIQozWhMMR3Lhfe_trk,12148
|
|
792
|
-
endoreg_db-0.8.5.
|
|
793
|
-
endoreg_db-0.8.5.
|
|
794
|
-
endoreg_db-0.8.5.
|
|
795
|
-
endoreg_db-0.8.5.
|
|
792
|
+
endoreg_db-0.8.5.9.dist-info/METADATA,sha256=4-1Z05Jr1iUfBysfq9viQcgDglBt4PBVX8B5BvsKmzc,14719
|
|
793
|
+
endoreg_db-0.8.5.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
794
|
+
endoreg_db-0.8.5.9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
795
|
+
endoreg_db-0.8.5.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|