endoreg-db 0.8.3.0__py3-none-any.whl → 0.8.3.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.
- endoreg_db/services/video_import.py +97 -130
- endoreg_db/tasks/video_processing_tasks.py +4 -4
- {endoreg_db-0.8.3.0.dist-info → endoreg_db-0.8.3.2.dist-info}/METADATA +2 -2
- {endoreg_db-0.8.3.0.dist-info → endoreg_db-0.8.3.2.dist-info}/RECORD +6 -6
- {endoreg_db-0.8.3.0.dist-info → endoreg_db-0.8.3.2.dist-info}/WHEEL +0 -0
- {endoreg_db-0.8.3.0.dist-info → endoreg_db-0.8.3.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -19,16 +19,12 @@ from pathlib import Path
|
|
|
19
19
|
from typing import Union, Dict, Any, Optional, List, Tuple
|
|
20
20
|
from django.db import transaction
|
|
21
21
|
from endoreg_db.models import VideoFile, SensitiveMeta
|
|
22
|
-
from endoreg_db.utils.paths import STORAGE_DIR,
|
|
22
|
+
from endoreg_db.utils.paths import STORAGE_DIR, VIDEO_DIR, ANONYM_VIDEO_DIR
|
|
23
23
|
import random
|
|
24
|
-
from lx_anonymizer.ocr import trocr_full_image_ocr
|
|
25
24
|
from endoreg_db.utils.hashs import get_video_hash
|
|
26
|
-
from endoreg_db.models.media.video.video_file_anonymize import _cleanup_raw_assets
|
|
27
|
-
from typing import TYPE_CHECKING
|
|
25
|
+
from endoreg_db.models.media.video.video_file_anonymize import _cleanup_raw_assets
|
|
28
26
|
from django.db.models.fields.files import FieldFile
|
|
29
|
-
|
|
30
|
-
if TYPE_CHECKING:
|
|
31
|
-
from endoreg_db.models import EndoscopyProcessor
|
|
27
|
+
from endoreg_db.models import EndoscopyProcessor
|
|
32
28
|
|
|
33
29
|
# File lock configuration (matches PDF import)
|
|
34
30
|
STALE_LOCK_SECONDS = 6000 # 100 minutes - reclaim locks older than this
|
|
@@ -58,15 +54,13 @@ class VideoImportService():
|
|
|
58
54
|
self.project_root = Path(__file__).parent.parent.parent.parent
|
|
59
55
|
|
|
60
56
|
# Track processed files to prevent duplicates
|
|
61
|
-
self.processed_files = set(str(file) for file in os.listdir(ANONYM_VIDEO_DIR))
|
|
62
|
-
|
|
63
|
-
self.STORAGE_DIR = STORAGE_DIR
|
|
64
|
-
|
|
57
|
+
self.processed_files = set(str(Path(ANONYM_VIDEO_DIR) / file) for file in os.listdir(ANONYM_VIDEO_DIR))
|
|
58
|
+
|
|
65
59
|
# Central video instance and processing context
|
|
66
60
|
self.current_video: Optional[VideoFile] = None
|
|
67
61
|
self.processing_context: Dict[str, Any] = {}
|
|
68
62
|
|
|
69
|
-
self.delete_source =
|
|
63
|
+
self.delete_source = True
|
|
70
64
|
|
|
71
65
|
self.logger = logging.getLogger(__name__)
|
|
72
66
|
|
|
@@ -166,12 +160,12 @@ class VideoImportService():
|
|
|
166
160
|
return None
|
|
167
161
|
raise
|
|
168
162
|
|
|
169
|
-
# Create sensitive meta file, ensure raw is moved out of processing folder watched by file watcher.
|
|
170
|
-
self._create_sensitive_file()
|
|
171
|
-
|
|
172
163
|
# Create or retrieve video instance
|
|
173
164
|
self._create_or_retrieve_video_instance()
|
|
174
165
|
|
|
166
|
+
# Create sensitive meta file, ensure raw is moved out of processing folder watched by file watcher.
|
|
167
|
+
self._create_sensitive_file()
|
|
168
|
+
|
|
175
169
|
# Setup processing environment
|
|
176
170
|
self._setup_processing_environment()
|
|
177
171
|
|
|
@@ -225,8 +219,12 @@ class VideoImportService():
|
|
|
225
219
|
|
|
226
220
|
# Acquire file lock to prevent concurrent processing
|
|
227
221
|
# Lock will be held until finally block in import_and_anonymize()
|
|
228
|
-
|
|
229
|
-
|
|
222
|
+
try:
|
|
223
|
+
self.processing_context['_lock_context'] = self._file_lock(file_path)
|
|
224
|
+
self.processing_context['_lock_context'].__enter__()
|
|
225
|
+
except Exception:
|
|
226
|
+
self._cleanup_processing_context()
|
|
227
|
+
raise
|
|
230
228
|
|
|
231
229
|
self.logger.info("Acquired file lock for: %s", file_path)
|
|
232
230
|
|
|
@@ -244,7 +242,6 @@ class VideoImportService():
|
|
|
244
242
|
|
|
245
243
|
def _create_or_retrieve_video_instance(self):
|
|
246
244
|
"""Create or retrieve the VideoFile instance and move to final storage."""
|
|
247
|
-
# Removed duplicate import of VideoFile (already imported at module level)
|
|
248
245
|
|
|
249
246
|
self.logger.info("Creating VideoFile instance...")
|
|
250
247
|
|
|
@@ -275,96 +272,78 @@ class VideoImportService():
|
|
|
275
272
|
def _move_to_final_storage(self):
|
|
276
273
|
"""
|
|
277
274
|
Move video from raw_videos to final storage locations.
|
|
278
|
-
- Raw video → /data/videos (raw_file_path)
|
|
275
|
+
- Raw video → /data/videos (raw_file_path)
|
|
279
276
|
- Processed video will later → /data/anonym_videos (file_path)
|
|
280
277
|
"""
|
|
281
278
|
from endoreg_db.utils import data_paths
|
|
282
|
-
|
|
283
|
-
source_path = self.processing_context['file_path']
|
|
284
279
|
|
|
285
|
-
|
|
286
|
-
|
|
280
|
+
source_path = Path(self.processing_context["file_path"])
|
|
281
|
+
_current_video = self._require_current_video()
|
|
282
|
+
videos_dir = Path(data_paths["video"])
|
|
283
|
+
storage_root = Path(data_paths["storage"])
|
|
287
284
|
|
|
288
|
-
|
|
289
|
-
assert _current_video is not None, "Current video instance is None during storage move"
|
|
285
|
+
videos_dir.mkdir(parents=True, exist_ok=True)
|
|
290
286
|
|
|
287
|
+
# --- Derive stored_raw_path safely ---
|
|
291
288
|
stored_raw_path = None
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
if stored_raw_path.is_absolute():
|
|
304
|
-
if not stored_raw_path.is_relative_to(storage_root):
|
|
289
|
+
try:
|
|
290
|
+
if hasattr(_current_video, "get_raw_file_path"):
|
|
291
|
+
candidate = _current_video.get_raw_file_path()
|
|
292
|
+
if candidate:
|
|
293
|
+
candidate_path = Path(candidate)
|
|
294
|
+
# Accept only if under storage_root
|
|
295
|
+
try:
|
|
296
|
+
candidate_path.relative_to(storage_root)
|
|
297
|
+
stored_raw_path = candidate_path
|
|
298
|
+
except ValueError:
|
|
299
|
+
# outside storage_root, reset
|
|
305
300
|
stored_raw_path = None
|
|
306
|
-
|
|
307
|
-
if stored_raw_path.parts and stored_raw_path.parts[0] == videos_dir.name:
|
|
308
|
-
stored_raw_path = storage_root / stored_raw_path
|
|
309
|
-
else:
|
|
310
|
-
stored_raw_path = videos_dir / stored_raw_path.name
|
|
311
|
-
except Exception:
|
|
312
|
-
stored_raw_path = None
|
|
313
|
-
|
|
314
|
-
if stored_raw_path and not stored_raw_path.suffix:
|
|
301
|
+
except Exception:
|
|
315
302
|
stored_raw_path = None
|
|
316
303
|
|
|
304
|
+
# Fallback: derive from UUID + suffix
|
|
317
305
|
if not stored_raw_path:
|
|
306
|
+
suffix = source_path.suffix or ".mp4"
|
|
318
307
|
uuid_str = getattr(_current_video, "uuid", None)
|
|
319
|
-
|
|
320
|
-
filename = f"{uuid_str}{source_suffix}" if uuid_str else Path(source_path).name
|
|
308
|
+
filename = f"{uuid_str}{suffix}" if uuid_str else source_path.name
|
|
321
309
|
stored_raw_path = videos_dir / filename
|
|
322
310
|
|
|
323
|
-
delete_source = bool(self.processing_context.get(
|
|
311
|
+
delete_source = bool(self.processing_context.get("delete_source", True))
|
|
324
312
|
stored_raw_path.parent.mkdir(parents=True, exist_ok=True)
|
|
325
313
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
shutil.move(str(source_path), str(stored_raw_path))
|
|
331
|
-
self.logger.info("Moved raw video to: %s", stored_raw_path)
|
|
332
|
-
else:
|
|
333
|
-
shutil.copy2(str(source_path), str(stored_raw_path))
|
|
334
|
-
self.logger.info("Copied raw video to: %s", stored_raw_path)
|
|
335
|
-
else:
|
|
336
|
-
raise FileNotFoundError(f"Neither stored raw path nor source path exists for {self.processing_context['file_path']}")
|
|
337
|
-
except Exception as e:
|
|
338
|
-
self.logger.error("Failed to place video in final storage: %s", e)
|
|
339
|
-
raise
|
|
340
|
-
else:
|
|
341
|
-
# If we already have the stored copy, respect delete_source flag without touching assets unnecessarily
|
|
342
|
-
if delete_source and source_path.exists():
|
|
314
|
+
# --- Move or copy raw video ---
|
|
315
|
+
try:
|
|
316
|
+
if delete_source:
|
|
317
|
+
# Try atomic move first, fallback to copy+unlink
|
|
343
318
|
try:
|
|
319
|
+
os.replace(source_path, stored_raw_path)
|
|
320
|
+
self.logger.info("Moved raw video to: %s", stored_raw_path)
|
|
321
|
+
except Exception:
|
|
322
|
+
shutil.copy2(source_path, stored_raw_path)
|
|
344
323
|
os.remove(source_path)
|
|
345
|
-
self.logger.info("
|
|
346
|
-
|
|
347
|
-
|
|
324
|
+
self.logger.info("Copied & removed raw video to: %s", stored_raw_path)
|
|
325
|
+
else:
|
|
326
|
+
shutil.copy2(source_path, stored_raw_path)
|
|
327
|
+
self.logger.info("Copied raw video to: %s", stored_raw_path)
|
|
328
|
+
except Exception as e:
|
|
329
|
+
self.logger.error("Failed to move/copy video to final storage: %s", e)
|
|
330
|
+
raise
|
|
348
331
|
|
|
349
|
-
# Ensure
|
|
332
|
+
# --- Ensure DB raw_file is relative to storage root ---
|
|
350
333
|
try:
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
self.logger.
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
self.logger.info("Updated raw_file path using fallback: %s", fallback_relative.as_posix())
|
|
334
|
+
rel_path = stored_raw_path.relative_to(storage_root)
|
|
335
|
+
except Exception:
|
|
336
|
+
rel_path = Path("videos") / stored_raw_path.name
|
|
337
|
+
|
|
338
|
+
if _current_video.raw_file.name != rel_path.as_posix():
|
|
339
|
+
_current_video.raw_file.name = rel_path.as_posix()
|
|
340
|
+
_current_video.save(update_fields=["raw_file"])
|
|
341
|
+
self.logger.info("Updated raw_file path to: %s", rel_path.as_posix())
|
|
342
|
+
|
|
343
|
+
# --- Store for later stages ---
|
|
344
|
+
self.processing_context["raw_video_path"] = stored_raw_path
|
|
345
|
+
self.processing_context["video_filename"] = stored_raw_path.name
|
|
364
346
|
|
|
365
|
-
# Store paths for later processing
|
|
366
|
-
self.processing_context['raw_video_path'] = Path(stored_raw_path)
|
|
367
|
-
self.processing_context['video_filename'] = Path(stored_raw_path).name
|
|
368
347
|
|
|
369
348
|
def _setup_processing_environment(self):
|
|
370
349
|
"""Setup the processing environment without file movement."""
|
|
@@ -406,7 +385,7 @@ class VideoImportService():
|
|
|
406
385
|
def _process_frames_and_metadata(self):
|
|
407
386
|
"""Process frames and extract metadata with anonymization."""
|
|
408
387
|
# Check frame cleaning availability
|
|
409
|
-
frame_cleaning_available,
|
|
388
|
+
frame_cleaning_available, frame_cleaner = self._ensure_frame_cleaning_available()
|
|
410
389
|
video = self._require_current_video()
|
|
411
390
|
|
|
412
391
|
raw_file_field = video.raw_file
|
|
@@ -427,7 +406,7 @@ class VideoImportService():
|
|
|
427
406
|
from concurrent.futures import ThreadPoolExecutor, TimeoutError as FutureTimeoutError
|
|
428
407
|
|
|
429
408
|
with ThreadPoolExecutor(max_workers=1) as executor:
|
|
430
|
-
future = executor.submit(self._perform_frame_cleaning,
|
|
409
|
+
future = executor.submit(self._perform_frame_cleaning, endoscope_data_roi_nested, endoscope_image_roi)
|
|
431
410
|
try:
|
|
432
411
|
# Increased timeout to better accommodate ffmpeg + OCR
|
|
433
412
|
future.result(timeout=300)
|
|
@@ -473,6 +452,9 @@ class VideoImportService():
|
|
|
473
452
|
self.processing_context['error_reason'] = f"Frame cleaning failed: {e}, Fallback failed: {fallback_error}"
|
|
474
453
|
|
|
475
454
|
def _save_anonymized_video(self):
|
|
455
|
+
|
|
456
|
+
original_raw_file_path_to_delete = None
|
|
457
|
+
original_raw_frame_dir_to_delete = None
|
|
476
458
|
video = self._require_current_video()
|
|
477
459
|
anonymized_video_path = video.get_target_anonymized_video_path()
|
|
478
460
|
|
|
@@ -760,6 +742,17 @@ class VideoImportService():
|
|
|
760
742
|
except Exception as exc:
|
|
761
743
|
self.logger.error("Failed to retrieve processor ROI information: %s", exc)
|
|
762
744
|
|
|
745
|
+
# Convert dict to nested list if necessary to match return type
|
|
746
|
+
if isinstance(endoscope_data_roi_nested, dict):
|
|
747
|
+
# Convert dict[str, dict[str, int | None] | None] to List[List[Dict[str, Any]]]
|
|
748
|
+
converted_roi = []
|
|
749
|
+
for key, value in endoscope_data_roi_nested.items():
|
|
750
|
+
if isinstance(value, dict):
|
|
751
|
+
converted_roi.append([value])
|
|
752
|
+
elif value is None:
|
|
753
|
+
converted_roi.append([])
|
|
754
|
+
endoscope_data_roi_nested = converted_roi
|
|
755
|
+
|
|
763
756
|
return endoscope_data_roi_nested, endoscope_image_roi
|
|
764
757
|
|
|
765
758
|
def _ensure_default_patient_data(self, video_instance: VideoFile | None = None) -> None:
|
|
@@ -781,8 +774,6 @@ class VideoImportService():
|
|
|
781
774
|
sensitive_meta = SensitiveMeta.create_from_dict(default_data)
|
|
782
775
|
video.sensitive_meta = sensitive_meta
|
|
783
776
|
video.save(update_fields=["sensitive_meta"])
|
|
784
|
-
state = video.get_or_create_state()
|
|
785
|
-
state.mark_sensitive_meta_processed(save=True)
|
|
786
777
|
self.logger.info("Created default SensitiveMeta for video %s", video.uuid)
|
|
787
778
|
except Exception as exc:
|
|
788
779
|
self.logger.error("Failed to create default SensitiveMeta for video %s: %s", video.uuid, exc)
|
|
@@ -821,67 +812,43 @@ class VideoImportService():
|
|
|
821
812
|
Tuple of (availability_flag, FrameCleaner_class, ReportReader_class)
|
|
822
813
|
"""
|
|
823
814
|
try:
|
|
824
|
-
# Check if we can find
|
|
825
|
-
from
|
|
826
|
-
lx_anonymizer_path = resources.files("lx_anonymizer")
|
|
815
|
+
# Check if we can find lx-anonymizer
|
|
816
|
+
from lx_anonymizer import FrameCleaner # type: ignore[import]
|
|
827
817
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
if lx_anonymizer_path.exists():
|
|
832
|
-
# Add to Python path temporarily
|
|
833
|
-
if str(lx_anonymizer_path) not in sys.path:
|
|
834
|
-
sys.path.insert(0, str(lx_anonymizer_path))
|
|
835
|
-
|
|
836
|
-
# Try simple import
|
|
837
|
-
from lx_anonymizer import FrameCleaner, ReportReader
|
|
838
|
-
|
|
839
|
-
self.logger.info("Successfully imported lx_anonymizer modules")
|
|
840
|
-
|
|
841
|
-
# Remove from path to avoid conflicts
|
|
842
|
-
if str(lx_anonymizer_path) in sys.path:
|
|
843
|
-
sys.path.remove(str(lx_anonymizer_path))
|
|
844
|
-
|
|
845
|
-
return True, FrameCleaner, ReportReader
|
|
846
|
-
|
|
847
|
-
else:
|
|
848
|
-
self.logger.warning(f"lx-anonymizer path not found: {lx_anonymizer_path}")
|
|
849
|
-
|
|
818
|
+
if FrameCleaner:
|
|
819
|
+
return True, FrameCleaner
|
|
820
|
+
|
|
850
821
|
except Exception as e:
|
|
851
|
-
self.logger.warning(f"Frame cleaning not available: {e}")
|
|
822
|
+
self.logger.warning(f"Frame cleaning not available: {e} Please install or update lx_anonymizer.")
|
|
852
823
|
|
|
853
|
-
return False, None
|
|
824
|
+
return False, None
|
|
854
825
|
|
|
855
826
|
|
|
856
827
|
|
|
857
|
-
def _perform_frame_cleaning(self,
|
|
828
|
+
def _perform_frame_cleaning(self, endoscope_data_roi_nested, endoscope_image_roi):
|
|
858
829
|
"""Perform frame cleaning and anonymization."""
|
|
859
830
|
# Instantiate frame cleaner
|
|
860
|
-
frame_cleaner =
|
|
861
|
-
|
|
831
|
+
is_available, frame_cleaner = self._ensure_frame_cleaning_available()
|
|
832
|
+
|
|
833
|
+
if not is_available:
|
|
834
|
+
raise RuntimeError("Frame cleaning not available")
|
|
835
|
+
|
|
862
836
|
# Prepare parameters for frame cleaning
|
|
863
837
|
raw_video_path = self.processing_context.get('raw_video_path')
|
|
864
838
|
|
|
865
839
|
if not raw_video_path or not Path(raw_video_path).exists():
|
|
866
840
|
raise RuntimeError(f"Raw video path not found: {raw_video_path}")
|
|
867
|
-
|
|
868
|
-
# Get processor name safely
|
|
869
|
-
video = self._require_current_video()
|
|
870
|
-
video_meta = getattr(video, "video_meta", None)
|
|
871
|
-
processor = getattr(video_meta, "processor", None) if video_meta else None
|
|
872
|
-
device_name = processor.name if processor else self.processing_context['processor_name']
|
|
841
|
+
|
|
873
842
|
|
|
874
843
|
# Create temporary output path for cleaned video
|
|
875
844
|
video_filename = self.processing_context.get('video_filename', Path(raw_video_path).name)
|
|
876
845
|
cleaned_filename = f"cleaned_{video_filename}"
|
|
877
846
|
cleaned_video_path = Path(raw_video_path).parent / cleaned_filename
|
|
878
847
|
|
|
879
|
-
# Processor roi is used later to OCR preknown regions.
|
|
880
848
|
|
|
881
849
|
# Clean video with ROI masking (heavy I/O operation)
|
|
882
850
|
actual_cleaned_path, extracted_metadata = frame_cleaner.clean_video(
|
|
883
851
|
video_path=Path(raw_video_path),
|
|
884
|
-
video_file_obj=video,
|
|
885
852
|
endoscope_image_roi=endoscope_image_roi,
|
|
886
853
|
endoscope_data_roi_nested=endoscope_data_roi_nested,
|
|
887
854
|
output_path=cleaned_video_path,
|
|
@@ -1024,7 +991,7 @@ def import_and_anonymize(
|
|
|
1024
991
|
center_name: str,
|
|
1025
992
|
processor_name: str,
|
|
1026
993
|
save_video: bool = True,
|
|
1027
|
-
delete_source: bool =
|
|
994
|
+
delete_source: bool = True,
|
|
1028
995
|
) -> VideoFile | None:
|
|
1029
996
|
"""Module-level helper that instantiates VideoImportService and runs import_and_anonymize.
|
|
1030
997
|
Kept for backward compatibility with callers that import this function directly.
|
|
@@ -53,7 +53,7 @@ def apply_video_mask_task(self, video_id: int, mask_type: str = 'device_default'
|
|
|
53
53
|
self.update_state(state='PROGRESS', meta={'progress': 10, 'message': 'Setting up FrameCleaner...'})
|
|
54
54
|
|
|
55
55
|
# Initialize FrameCleaner
|
|
56
|
-
cleaner = FrameCleaner(
|
|
56
|
+
cleaner = FrameCleaner()
|
|
57
57
|
|
|
58
58
|
# Determine mask configuration
|
|
59
59
|
if mask_type == 'custom' and custom_mask:
|
|
@@ -110,14 +110,14 @@ def _setup_frame_removal(video_id: int, detection_engine: str):
|
|
|
110
110
|
from lx_anonymizer.frame_cleaner import FrameCleaner
|
|
111
111
|
from django.shortcuts import get_object_or_404
|
|
112
112
|
video = get_object_or_404(VideoFile, pk=video_id)
|
|
113
|
-
video_path = Path(video.
|
|
113
|
+
video_path = Path(video.raw_file.path)
|
|
114
114
|
if not video_path.exists():
|
|
115
115
|
raise FileNotFoundError(f"Video file not found: {video_path}")
|
|
116
116
|
output_dir = video_path.parent / "processed"
|
|
117
117
|
output_dir.mkdir(exist_ok=True)
|
|
118
118
|
output_path = output_dir / f"{video_path.stem}_cleaned{video_path.suffix}"
|
|
119
119
|
use_minicpm = detection_engine == 'minicpm'
|
|
120
|
-
cleaner = FrameCleaner(
|
|
120
|
+
cleaner = FrameCleaner()
|
|
121
121
|
return video, video_path, output_path, cleaner
|
|
122
122
|
|
|
123
123
|
def _detect_sensitive_frames(self, cleaner, video_path, selection_method, manual_frames, total_frames):
|
|
@@ -257,7 +257,7 @@ def reprocess_video_task(self, video_id: int):
|
|
|
257
257
|
self.update_state(state='PROGRESS', meta={'progress': 20, 'message': 'Initializing FrameCleaner...'})
|
|
258
258
|
|
|
259
259
|
# Initialize FrameCleaner with optimal settings
|
|
260
|
-
cleaner = FrameCleaner(
|
|
260
|
+
cleaner = FrameCleaner()
|
|
261
261
|
|
|
262
262
|
# Create output path
|
|
263
263
|
output_dir = video_path.parent / "processed"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: endoreg-db
|
|
3
|
-
Version: 0.8.3.
|
|
3
|
+
Version: 0.8.3.2
|
|
4
4
|
Summary: EndoReg Db Django App
|
|
5
5
|
Project-URL: Homepage, https://info.coloreg.de
|
|
6
6
|
Project-URL: Repository, https://github.com/wg-lux/endoreg-db
|
|
@@ -33,7 +33,7 @@ Requires-Dist: huggingface-hub>=0.35.3
|
|
|
33
33
|
Requires-Dist: icecream>=2.1.4
|
|
34
34
|
Requires-Dist: librosa==0.11.0
|
|
35
35
|
Requires-Dist: llvmlite>=0.44.0
|
|
36
|
-
Requires-Dist: lx-anonymizer[llm,ocr]>=0.8.
|
|
36
|
+
Requires-Dist: lx-anonymizer[llm,ocr]>=0.8.8
|
|
37
37
|
Requires-Dist: moviepy==2.2.1
|
|
38
38
|
Requires-Dist: mypy>=1.16.0
|
|
39
39
|
Requires-Dist: numpy>=2.2.3
|
|
@@ -600,10 +600,10 @@ endoreg_db/services/pseudonym_service.py,sha256=CJhbtRa6K6SPbphgCZgEMi8AFQtB18CU
|
|
|
600
600
|
endoreg_db/services/requirements_object.py,sha256=290zf8AEbVtCoHhW4Jr7_ud-RvrqYmb1Nz9UBHtTnc0,6164
|
|
601
601
|
endoreg_db/services/segment_sync.py,sha256=YgHvIHkbW4mqCu0ACf3zjRSZnNfxWwt4gh5syUVXuE0,6400
|
|
602
602
|
endoreg_db/services/storage_aware_video_processor.py,sha256=kKFK64vXLeBSVkp1YJonU3gFDTeXZ8C4qb9QZZB99SE,13420
|
|
603
|
-
endoreg_db/services/video_import.py,sha256=
|
|
603
|
+
endoreg_db/services/video_import.py,sha256=gDuVTW5WUYGSc0m5ly67cc10YpnTpBkxO7uOEcRa3Ok,45663
|
|
604
604
|
endoreg_db/tasks/upload_tasks.py,sha256=OJq7DhNwcbWdXzHY8jz5c51BCVkPN5gSWOz-6Fx6W5M,7799
|
|
605
605
|
endoreg_db/tasks/video_ingest.py,sha256=kxFuYkHijINV0VabQKCFVpJRv6eCAw07tviONurDgg8,5265
|
|
606
|
-
endoreg_db/tasks/video_processing_tasks.py,sha256=
|
|
606
|
+
endoreg_db/tasks/video_processing_tasks.py,sha256=rZ7Kr49bAR4Q-vALO2SURebrhcJ5hSFGwjF4aULrOao,14089
|
|
607
607
|
endoreg_db/templates/timeline.html,sha256=H9VXKOecCzqcWWkpNIZXFI29ztg-oxV5uvxMglgoClk,6167
|
|
608
608
|
endoreg_db/templates/admin/patient_finding_intervention.html,sha256=F3JUKm3HhWIf_xoZZ-SET5d5ZDlm2jMM8g909w1dnYc,10164
|
|
609
609
|
endoreg_db/templates/admin/start_examination.html,sha256=3K4wirul9KNyB5mN9cpfCSCAyAD6ro19GwxFOY5sZ3A,267
|
|
@@ -784,7 +784,7 @@ endoreg_db/views/video/video_meta.py,sha256=C1wBMTtQb_yzEUrhFGAy2UHEWMk_CbU75WXX
|
|
|
784
784
|
endoreg_db/views/video/video_processing_history.py,sha256=mhFuS8RG5GV8E-lTtuD0qrq-bIpnUFp8vy9aERfC-J8,770
|
|
785
785
|
endoreg_db/views/video/video_remove_frames.py,sha256=2FmvNrSPM0fUXiBxINN6vBUUDCqDlBkNcGR3WsLDgKo,1696
|
|
786
786
|
endoreg_db/views/video/video_stream.py,sha256=kLyuf0ORTmsLeYUQkTQ6iRYqlIQozWhMMR3Lhfe_trk,12148
|
|
787
|
-
endoreg_db-0.8.3.
|
|
788
|
-
endoreg_db-0.8.3.
|
|
789
|
-
endoreg_db-0.8.3.
|
|
790
|
-
endoreg_db-0.8.3.
|
|
787
|
+
endoreg_db-0.8.3.2.dist-info/METADATA,sha256=Hdg0xL9WKegEgoyGOY0vgwAX1UVB87Ph86WNsYgcSms,14758
|
|
788
|
+
endoreg_db-0.8.3.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
789
|
+
endoreg_db-0.8.3.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
790
|
+
endoreg_db-0.8.3.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|