endoreg-db 0.8.3.1__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 +94 -126
- endoreg_db/tasks/video_processing_tasks.py +4 -4
- {endoreg_db-0.8.3.1.dist-info → endoreg_db-0.8.3.2.dist-info}/METADATA +2 -2
- {endoreg_db-0.8.3.1.dist-info → endoreg_db-0.8.3.2.dist-info}/RECORD +6 -6
- {endoreg_db-0.8.3.1.dist-info → endoreg_db-0.8.3.2.dist-info}/WHEEL +0 -0
- {endoreg_db-0.8.3.1.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
|
|
|
@@ -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
|
|
|
@@ -274,96 +272,78 @@ class VideoImportService():
|
|
|
274
272
|
def _move_to_final_storage(self):
|
|
275
273
|
"""
|
|
276
274
|
Move video from raw_videos to final storage locations.
|
|
277
|
-
- Raw video → /data/videos (raw_file_path)
|
|
275
|
+
- Raw video → /data/videos (raw_file_path)
|
|
278
276
|
- Processed video will later → /data/anonym_videos (file_path)
|
|
279
277
|
"""
|
|
280
278
|
from endoreg_db.utils import data_paths
|
|
281
|
-
|
|
282
|
-
source_path = self.processing_context['file_path']
|
|
283
279
|
|
|
284
|
-
|
|
285
|
-
|
|
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"])
|
|
286
284
|
|
|
287
|
-
|
|
288
|
-
assert _current_video is not None, "Current video instance is None during storage move"
|
|
285
|
+
videos_dir.mkdir(parents=True, exist_ok=True)
|
|
289
286
|
|
|
287
|
+
# --- Derive stored_raw_path safely ---
|
|
290
288
|
stored_raw_path = None
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if stored_raw_path.is_absolute():
|
|
303
|
-
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
|
|
304
300
|
stored_raw_path = None
|
|
305
|
-
|
|
306
|
-
if stored_raw_path.parts and stored_raw_path.parts[0] == videos_dir.name:
|
|
307
|
-
stored_raw_path = storage_root / stored_raw_path
|
|
308
|
-
else:
|
|
309
|
-
stored_raw_path = videos_dir / stored_raw_path.name
|
|
310
|
-
except Exception:
|
|
311
|
-
stored_raw_path = None
|
|
312
|
-
|
|
313
|
-
if stored_raw_path and not stored_raw_path.suffix:
|
|
301
|
+
except Exception:
|
|
314
302
|
stored_raw_path = None
|
|
315
303
|
|
|
304
|
+
# Fallback: derive from UUID + suffix
|
|
316
305
|
if not stored_raw_path:
|
|
306
|
+
suffix = source_path.suffix or ".mp4"
|
|
317
307
|
uuid_str = getattr(_current_video, "uuid", None)
|
|
318
|
-
|
|
319
|
-
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
|
|
320
309
|
stored_raw_path = videos_dir / filename
|
|
321
310
|
|
|
322
|
-
delete_source = bool(self.processing_context.get(
|
|
311
|
+
delete_source = bool(self.processing_context.get("delete_source", True))
|
|
323
312
|
stored_raw_path.parent.mkdir(parents=True, exist_ok=True)
|
|
324
313
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
shutil.move(str(source_path), str(stored_raw_path))
|
|
330
|
-
self.logger.info("Moved raw video to: %s", stored_raw_path)
|
|
331
|
-
else:
|
|
332
|
-
shutil.copy2(str(source_path), str(stored_raw_path))
|
|
333
|
-
self.logger.info("Copied raw video to: %s", stored_raw_path)
|
|
334
|
-
else:
|
|
335
|
-
raise FileNotFoundError(f"Neither stored raw path nor source path exists for {self.processing_context['file_path']}")
|
|
336
|
-
except Exception as e:
|
|
337
|
-
self.logger.error("Failed to place video in final storage: %s", e)
|
|
338
|
-
raise
|
|
339
|
-
else:
|
|
340
|
-
# If we already have the stored copy, respect delete_source flag without touching assets unnecessarily
|
|
341
|
-
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
|
|
342
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)
|
|
343
323
|
os.remove(source_path)
|
|
344
|
-
self.logger.info("
|
|
345
|
-
|
|
346
|
-
|
|
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
|
|
347
331
|
|
|
348
|
-
# Ensure
|
|
332
|
+
# --- Ensure DB raw_file is relative to storage root ---
|
|
349
333
|
try:
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
self.logger.
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
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
|
|
363
346
|
|
|
364
|
-
# Store paths for later processing
|
|
365
|
-
self.processing_context['raw_video_path'] = Path(stored_raw_path)
|
|
366
|
-
self.processing_context['video_filename'] = Path(stored_raw_path).name
|
|
367
347
|
|
|
368
348
|
def _setup_processing_environment(self):
|
|
369
349
|
"""Setup the processing environment without file movement."""
|
|
@@ -405,7 +385,7 @@ class VideoImportService():
|
|
|
405
385
|
def _process_frames_and_metadata(self):
|
|
406
386
|
"""Process frames and extract metadata with anonymization."""
|
|
407
387
|
# Check frame cleaning availability
|
|
408
|
-
frame_cleaning_available,
|
|
388
|
+
frame_cleaning_available, frame_cleaner = self._ensure_frame_cleaning_available()
|
|
409
389
|
video = self._require_current_video()
|
|
410
390
|
|
|
411
391
|
raw_file_field = video.raw_file
|
|
@@ -426,7 +406,7 @@ class VideoImportService():
|
|
|
426
406
|
from concurrent.futures import ThreadPoolExecutor, TimeoutError as FutureTimeoutError
|
|
427
407
|
|
|
428
408
|
with ThreadPoolExecutor(max_workers=1) as executor:
|
|
429
|
-
future = executor.submit(self._perform_frame_cleaning,
|
|
409
|
+
future = executor.submit(self._perform_frame_cleaning, endoscope_data_roi_nested, endoscope_image_roi)
|
|
430
410
|
try:
|
|
431
411
|
# Increased timeout to better accommodate ffmpeg + OCR
|
|
432
412
|
future.result(timeout=300)
|
|
@@ -472,6 +452,9 @@ class VideoImportService():
|
|
|
472
452
|
self.processing_context['error_reason'] = f"Frame cleaning failed: {e}, Fallback failed: {fallback_error}"
|
|
473
453
|
|
|
474
454
|
def _save_anonymized_video(self):
|
|
455
|
+
|
|
456
|
+
original_raw_file_path_to_delete = None
|
|
457
|
+
original_raw_frame_dir_to_delete = None
|
|
475
458
|
video = self._require_current_video()
|
|
476
459
|
anonymized_video_path = video.get_target_anonymized_video_path()
|
|
477
460
|
|
|
@@ -759,6 +742,17 @@ class VideoImportService():
|
|
|
759
742
|
except Exception as exc:
|
|
760
743
|
self.logger.error("Failed to retrieve processor ROI information: %s", exc)
|
|
761
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
|
+
|
|
762
756
|
return endoscope_data_roi_nested, endoscope_image_roi
|
|
763
757
|
|
|
764
758
|
def _ensure_default_patient_data(self, video_instance: VideoFile | None = None) -> None:
|
|
@@ -780,8 +774,6 @@ class VideoImportService():
|
|
|
780
774
|
sensitive_meta = SensitiveMeta.create_from_dict(default_data)
|
|
781
775
|
video.sensitive_meta = sensitive_meta
|
|
782
776
|
video.save(update_fields=["sensitive_meta"])
|
|
783
|
-
state = video.get_or_create_state()
|
|
784
|
-
state.mark_sensitive_meta_processed(save=True)
|
|
785
777
|
self.logger.info("Created default SensitiveMeta for video %s", video.uuid)
|
|
786
778
|
except Exception as exc:
|
|
787
779
|
self.logger.error("Failed to create default SensitiveMeta for video %s: %s", video.uuid, exc)
|
|
@@ -820,67 +812,43 @@ class VideoImportService():
|
|
|
820
812
|
Tuple of (availability_flag, FrameCleaner_class, ReportReader_class)
|
|
821
813
|
"""
|
|
822
814
|
try:
|
|
823
|
-
# Check if we can find
|
|
824
|
-
from
|
|
825
|
-
lx_anonymizer_path = resources.files("lx_anonymizer")
|
|
815
|
+
# Check if we can find lx-anonymizer
|
|
816
|
+
from lx_anonymizer import FrameCleaner # type: ignore[import]
|
|
826
817
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
if lx_anonymizer_path.exists():
|
|
831
|
-
# Add to Python path temporarily
|
|
832
|
-
if str(lx_anonymizer_path) not in sys.path:
|
|
833
|
-
sys.path.insert(0, str(lx_anonymizer_path))
|
|
834
|
-
|
|
835
|
-
# Try simple import
|
|
836
|
-
from lx_anonymizer import FrameCleaner, ReportReader
|
|
837
|
-
|
|
838
|
-
self.logger.info("Successfully imported lx_anonymizer modules")
|
|
839
|
-
|
|
840
|
-
# Remove from path to avoid conflicts
|
|
841
|
-
if str(lx_anonymizer_path) in sys.path:
|
|
842
|
-
sys.path.remove(str(lx_anonymizer_path))
|
|
843
|
-
|
|
844
|
-
return True, FrameCleaner, ReportReader
|
|
845
|
-
|
|
846
|
-
else:
|
|
847
|
-
self.logger.warning(f"lx-anonymizer path not found: {lx_anonymizer_path}")
|
|
848
|
-
|
|
818
|
+
if FrameCleaner:
|
|
819
|
+
return True, FrameCleaner
|
|
820
|
+
|
|
849
821
|
except Exception as e:
|
|
850
|
-
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.")
|
|
851
823
|
|
|
852
|
-
return False, None
|
|
824
|
+
return False, None
|
|
853
825
|
|
|
854
826
|
|
|
855
827
|
|
|
856
|
-
def _perform_frame_cleaning(self,
|
|
828
|
+
def _perform_frame_cleaning(self, endoscope_data_roi_nested, endoscope_image_roi):
|
|
857
829
|
"""Perform frame cleaning and anonymization."""
|
|
858
830
|
# Instantiate frame cleaner
|
|
859
|
-
frame_cleaner =
|
|
860
|
-
|
|
831
|
+
is_available, frame_cleaner = self._ensure_frame_cleaning_available()
|
|
832
|
+
|
|
833
|
+
if not is_available:
|
|
834
|
+
raise RuntimeError("Frame cleaning not available")
|
|
835
|
+
|
|
861
836
|
# Prepare parameters for frame cleaning
|
|
862
837
|
raw_video_path = self.processing_context.get('raw_video_path')
|
|
863
838
|
|
|
864
839
|
if not raw_video_path or not Path(raw_video_path).exists():
|
|
865
840
|
raise RuntimeError(f"Raw video path not found: {raw_video_path}")
|
|
866
|
-
|
|
867
|
-
# Get processor name safely
|
|
868
|
-
video = self._require_current_video()
|
|
869
|
-
video_meta = getattr(video, "video_meta", None)
|
|
870
|
-
processor = getattr(video_meta, "processor", None) if video_meta else None
|
|
871
|
-
device_name = processor.name if processor else self.processing_context['processor_name']
|
|
841
|
+
|
|
872
842
|
|
|
873
843
|
# Create temporary output path for cleaned video
|
|
874
844
|
video_filename = self.processing_context.get('video_filename', Path(raw_video_path).name)
|
|
875
845
|
cleaned_filename = f"cleaned_{video_filename}"
|
|
876
846
|
cleaned_video_path = Path(raw_video_path).parent / cleaned_filename
|
|
877
847
|
|
|
878
|
-
# Processor roi is used later to OCR preknown regions.
|
|
879
848
|
|
|
880
849
|
# Clean video with ROI masking (heavy I/O operation)
|
|
881
850
|
actual_cleaned_path, extracted_metadata = frame_cleaner.clean_video(
|
|
882
851
|
video_path=Path(raw_video_path),
|
|
883
|
-
video_file_obj=video,
|
|
884
852
|
endoscope_image_roi=endoscope_image_roi,
|
|
885
853
|
endoscope_data_roi_nested=endoscope_data_roi_nested,
|
|
886
854
|
output_path=cleaned_video_path,
|
|
@@ -1023,7 +991,7 @@ def import_and_anonymize(
|
|
|
1023
991
|
center_name: str,
|
|
1024
992
|
processor_name: str,
|
|
1025
993
|
save_video: bool = True,
|
|
1026
|
-
delete_source: bool =
|
|
994
|
+
delete_source: bool = True,
|
|
1027
995
|
) -> VideoFile | None:
|
|
1028
996
|
"""Module-level helper that instantiates VideoImportService and runs import_and_anonymize.
|
|
1029
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
|