lots of fixes
This commit is contained in:
+6
-1
@@ -4,4 +4,9 @@
|
||||
logs/*
|
||||
|
||||
.pyc
|
||||
__pycache__/*
|
||||
__pycache__/*
|
||||
|
||||
build
|
||||
dist
|
||||
|
||||
*.build
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
@echo off
|
||||
rem This script was created by Nuitka to execute 'anon_gui.exe' with Python DLL being found.
|
||||
set PATH=C:\PROGRA~1\PYTHON~1;%PATH%
|
||||
set PYTHONHOME=C:\Program Files\Python311
|
||||
"%~dp0anon_gui.exe" %*
|
||||
Binary file not shown.
+162
-115
@@ -55,8 +55,11 @@ import hashlib
|
||||
|
||||
try:
|
||||
from agw import hyperlink as hl
|
||||
from agw import pygauge as PG
|
||||
except ImportError: # if it's not there locally, try the wxPython lib.
|
||||
import wx.lib.agw.hyperlink as hl
|
||||
import wx.lib.agw.pygauge as PG
|
||||
|
||||
|
||||
|
||||
import wx.lib.agw.thumbnailctrl as TC
|
||||
@@ -565,7 +568,7 @@ class AnonGui(wx.App):
|
||||
self.series_grid = SeriesGrid(self.panel)
|
||||
|
||||
if self.clear_files_on_start:
|
||||
self.ClearFiles()
|
||||
self.ClearFiles(load_dir=False)
|
||||
|
||||
self.panel.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
@@ -627,7 +630,6 @@ class AnonGui(wx.App):
|
||||
self.list_ctrl.InsertColumn(6, "Hash")
|
||||
self.list_ctrl.InsertColumn(7, "Series Instance UID")
|
||||
|
||||
self.AnnonymiseFilesInDir(self.input_dir, self.dir)
|
||||
|
||||
# self.UpdateListCtrl()
|
||||
|
||||
@@ -673,12 +675,23 @@ class AnonGui(wx.App):
|
||||
self.panel.sizer.Add(self.drag_button, 2, wx.EXPAND)
|
||||
self.panel.sizer.Add(self.upload_button, 2, wx.EXPAND)
|
||||
|
||||
self.progress_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.progress_bar = wx.Gauge(self.panel, style=wx.GA_HORIZONTAL|wx.GA_PROGRESS)
|
||||
#self.progress_bar = PG.PyGauge(self.panel, style=wx.GA_HORIZONTAL|wx.GA_PROGRESS)
|
||||
#self.progress_bar.SetDrawValue(draw=True, drawPercent=True, font=None, colour=wx.RED, formatString=None)
|
||||
self.progress_text = wx.StaticText(self.panel, label="Text")
|
||||
self.progress_sizer.Add(self.progress_bar, 2, wx.EXPAND)
|
||||
self.progress_sizer.Add(self.progress_text, 2, wx.EXPAND)
|
||||
self.panel.sizer.Add(self.progress_sizer, 2, wx.EXPAND)
|
||||
self.progress_sizer.ShowItems(show=False)
|
||||
|
||||
# Layout sizers
|
||||
self.panel.SetSizer(self.panel.sizer)
|
||||
self.panel.SetAutoLayout(1)
|
||||
self.panel.sizer.Fit(self.panel)
|
||||
self.frame.Show()
|
||||
# self.spinner.Hide()
|
||||
self.AnnonymiseFilesInDir(self.input_dir, self.dir)
|
||||
|
||||
self.Bind(wx.EVT_KEY_DOWN, self.onKeyPress)
|
||||
|
||||
@@ -717,29 +730,57 @@ class AnonGui(wx.App):
|
||||
|
||||
#files = order_files_by_dicom_attribute(files)
|
||||
|
||||
progress_dialog = wx.ProgressDialog(
|
||||
"Annonymise files",
|
||||
"Removing data...",
|
||||
maximum=len(files),
|
||||
style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME,
|
||||
)
|
||||
#progress_dialog = wx.ProgressDialog(
|
||||
# "Annonymise files",
|
||||
# "Removing data...",
|
||||
# maximum=len(files),
|
||||
# style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME,
|
||||
#)
|
||||
with self.progress(len(files), "Annonymise files") as p:
|
||||
#p.SetRange(len(files))
|
||||
|
||||
for n, file in enumerate(files):
|
||||
progress_dialog.Update(n)
|
||||
new_filepath: Path
|
||||
# Get next available filename
|
||||
i: int = 0
|
||||
while os.path.exists(
|
||||
new_filepath := output_dir.joinpath(f"IMG_{i:03}.dcm")
|
||||
):
|
||||
i += 1
|
||||
# new_filepath = Path(output_dir).joinpath(f"IMG_{i:03}.dcm")
|
||||
for n, file in enumerate(files):
|
||||
#progress_dialog.Update(n)
|
||||
p.update(n)
|
||||
new_filepath: Path
|
||||
# Get next available filename
|
||||
i: int = 0
|
||||
while os.path.exists(
|
||||
new_filepath := output_dir.joinpath(f"IMG_{i:03}.dcm")
|
||||
):
|
||||
i += 1
|
||||
# new_filepath = Path(output_dir).joinpath(f"IMG_{i:03}.dcm")
|
||||
|
||||
dataset, filepath = anonymize_file(file, new_filepath)
|
||||
self.add_datails_to_file_detail_map(dataset, filepath)
|
||||
progress_dialog.Destroy()
|
||||
dataset, filepath = anonymize_file(file, new_filepath)
|
||||
self.add_datails_to_file_detail_map(dataset, filepath)
|
||||
#progress_dialog.Destroy()
|
||||
|
||||
self.LoadDir(self.dir)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def progress(self, total: int, text: str="Working"):
|
||||
#self.progress_sizer.Show()
|
||||
self.progress_text.SetLabelText(text)
|
||||
self.progress_bar.SetRange(total)
|
||||
self.progress_sizer.ShowItems(show=True)
|
||||
self.panel.Layout()
|
||||
#self.panel.sizer.Fit(self.panel)
|
||||
try:
|
||||
class P():
|
||||
def __init__(self, gui, total, text):
|
||||
self.gui = gui
|
||||
self.text = text
|
||||
self.total = total
|
||||
def update(self, n: int):
|
||||
self.gui.progress_bar.SetValue(n)
|
||||
self.gui.progress_text.SetLabelText(f"{self.text} : {n}")
|
||||
yield P(self, total, text)
|
||||
finally:
|
||||
#self.progress_sizer.Hide()
|
||||
self.progress_sizer.ShowItems(show=False)
|
||||
self.panel.Layout()
|
||||
#self.panel.SetAutoLayout(1)
|
||||
#self.panel.sizer.Fit(self.panel)
|
||||
|
||||
def onKeyPress(self, event):
|
||||
keycode = event.GetKeyCode()
|
||||
@@ -774,7 +815,7 @@ class AnonGui(wx.App):
|
||||
|
||||
def OnExit(self):
|
||||
if self.clear_files_on_close:
|
||||
self.ClearFiles(close=True)
|
||||
self.ClearFiles(load_dir=False)
|
||||
|
||||
# self.zmq_thread.join()
|
||||
|
||||
@@ -915,12 +956,12 @@ class AnonGui(wx.App):
|
||||
|
||||
dlg.ShowModal()
|
||||
|
||||
def ClearFiles(self, event=None, close: bool=False):
|
||||
def ClearFiles(self, event=None, load_dir: bool=True):
|
||||
files = Path(self.dir).glob("*")
|
||||
for f in files:
|
||||
os.remove(f)
|
||||
|
||||
if not close:
|
||||
if load_dir:
|
||||
self.LoadDir(clear_file_detail_map=True)
|
||||
|
||||
def add_datails_to_file_detail_map(self, dataset, file):
|
||||
@@ -1020,66 +1061,69 @@ class AnonGui(wx.App):
|
||||
n = 0
|
||||
DATA = {}
|
||||
|
||||
progress_dialog = wx.ProgressDialog(
|
||||
"Loading files",
|
||||
"Extracting data from files",
|
||||
maximum=len(self.files),
|
||||
style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME,
|
||||
)
|
||||
#progress_dialog = wx.ProgressDialog(
|
||||
# "Loading files",
|
||||
# "Extracting data from files",
|
||||
# maximum=len(self.files),
|
||||
# style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME,
|
||||
#)
|
||||
with self.progress((len(self.files)), "Loading files") as p:
|
||||
#p.SetRange(len(self.files))
|
||||
|
||||
self.series_map = defaultdict(list)
|
||||
self.series_map_details = defaultdict(dict)
|
||||
self.series_map = defaultdict(list)
|
||||
self.series_map_details = defaultdict(dict)
|
||||
|
||||
hashes = []
|
||||
hashes = []
|
||||
|
||||
for n, f in enumerate(self.files):
|
||||
progress_dialog.Update(n)
|
||||
# dataset = pydicom.read_file(f)
|
||||
for n, f in enumerate(self.files):
|
||||
#progress_dialog.Update(n)
|
||||
p.update(n)
|
||||
# dataset = pydicom.read_file(f)
|
||||
|
||||
if f in self.file_detail_map:
|
||||
d, hash, d2 = self.file_detail_map[f]
|
||||
print("in map")
|
||||
else:
|
||||
if f in self.file_detail_map:
|
||||
d, hash, d2 = self.file_detail_map[f]
|
||||
print("in map")
|
||||
else:
|
||||
try:
|
||||
dataset = pydicom.dcmread(f)
|
||||
except FileNotFoundError:
|
||||
return
|
||||
|
||||
print("recalc")
|
||||
d, hash, d2 = self.add_datails_to_file_detail_map(dataset, f)
|
||||
|
||||
hashes.append(hash)
|
||||
|
||||
|
||||
series_instances_uid = d2["series_instances_uid"]
|
||||
try:
|
||||
dataset = pydicom.dcmread(f)
|
||||
except FileNotFoundError:
|
||||
return
|
||||
self.series_map[series_instances_uid].append(f)
|
||||
self.series_map_details[series_instances_uid][
|
||||
"series_description"
|
||||
] = d2["series_description"]
|
||||
self.series_map_details[series_instances_uid]["study_description"] = d2[
|
||||
"study_description"
|
||||
]
|
||||
self.series_map_details[series_instances_uid]["name"] = d2["name"]
|
||||
except:
|
||||
logger.debug(f"Unable to get Series Instance UID: {f.name}")
|
||||
|
||||
print("recalc")
|
||||
d, hash, d2 = self.add_datails_to_file_detail_map(dataset, f)
|
||||
logger.debug(d)
|
||||
DATA[n] = d
|
||||
self.list_ctrl.Append(d)
|
||||
self.list_ctrl.SetItemPyData(n, {"file": f, "hash": hash})
|
||||
self.list_ctrl.SetItemData(n, n)
|
||||
|
||||
hashes.append(hash)
|
||||
if f in self.file_duplicate_check:
|
||||
if self.file_duplicate_check[f]["id"]:
|
||||
self.list_ctrl.SetItemBackgroundColour(n, wx.RED)
|
||||
|
||||
|
||||
series_instances_uid = d2["series_instances_uid"]
|
||||
try:
|
||||
self.series_map[series_instances_uid].append(f)
|
||||
self.series_map_details[series_instances_uid][
|
||||
"series_description"
|
||||
] = d2["series_description"]
|
||||
self.series_map_details[series_instances_uid]["study_description"] = d2[
|
||||
"study_description"
|
||||
]
|
||||
self.series_map_details[series_instances_uid]["name"] = d2["name"]
|
||||
except:
|
||||
logger.debug(f"Unable to get Series Instance UID: {f.name}")
|
||||
|
||||
logger.debug(d)
|
||||
DATA[n] = d
|
||||
self.list_ctrl.Append(d)
|
||||
self.list_ctrl.SetItemPyData(n, {"file": f, "hash": hash})
|
||||
self.list_ctrl.SetItemData(n, n)
|
||||
|
||||
if f in self.file_duplicate_check:
|
||||
if self.file_duplicate_check[f]["id"]:
|
||||
self.list_ctrl.SetItemBackgroundColour(n, wx.RED)
|
||||
|
||||
n = n + 1
|
||||
n = n + 1
|
||||
self.list_ctrl.UpdateData(DATA)
|
||||
self.populate_series_grid()
|
||||
|
||||
|
||||
progress_dialog.Destroy()
|
||||
#progress_dialog.Destroy()
|
||||
|
||||
#if hashes:
|
||||
# self.check_image_hashes(hashes)
|
||||
@@ -1112,8 +1156,8 @@ class AnonGui(wx.App):
|
||||
for hash, dup in resp.json().items():
|
||||
self.file_duplicate_check[hash_file_map[hash]] = dup
|
||||
|
||||
print(self.file_duplicate_check)
|
||||
wx.CallAfter(self.UpdateListCtrl)
|
||||
if resp.json().items():
|
||||
wx.CallAfter(self.UpdateListCtrl)
|
||||
self.image_hash_check_in_progress = False
|
||||
|
||||
def OnColRightClick(self, event):
|
||||
@@ -1136,52 +1180,55 @@ class AnonGui(wx.App):
|
||||
files_to_upload[i : i + n] for i in range(0, len(files_to_upload), n)
|
||||
]
|
||||
|
||||
progress_dialog = wx.ProgressDialog(
|
||||
"Uploading files",
|
||||
"Uploading files. This is done in batches...",
|
||||
maximum=len(chunked_files),
|
||||
style=wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME,
|
||||
)
|
||||
#progress_dialog = wx.ProgressDialog(
|
||||
# "Uploading files",
|
||||
# "Uploading files. This is done in batches...",
|
||||
# maximum=len(chunked_files),
|
||||
# style=wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME,
|
||||
#)
|
||||
with self.progress(len(chunked_files), "Uploading files (in batches)") as p:
|
||||
#p.SetRange(len(chunked_files))
|
||||
|
||||
upload_file_list = []
|
||||
duplicate_file_list = []
|
||||
upload_file_list = []
|
||||
duplicate_file_list = []
|
||||
|
||||
for n, files in enumerate(chunked_files):
|
||||
for n, files in enumerate(chunked_files):
|
||||
|
||||
def upload_files(files):
|
||||
self.rqst.headers["X-CSRFToken"] = self.rqst.cookies["csrftoken"]
|
||||
# print(self.rqst.headers)
|
||||
# print(self.rqst.cookies)
|
||||
resp = self.rqst.post(
|
||||
f"{self.base_site_url}/api/atlas/upload_dicom",
|
||||
# data=data,
|
||||
files=files,
|
||||
)
|
||||
def upload_files(files):
|
||||
self.rqst.headers["X-CSRFToken"] = self.rqst.cookies["csrftoken"]
|
||||
# print(self.rqst.headers)
|
||||
# print(self.rqst.cookies)
|
||||
resp = self.rqst.post(
|
||||
f"{self.base_site_url}/api/atlas/upload_dicom",
|
||||
# data=data,
|
||||
files=files,
|
||||
)
|
||||
|
||||
logger.debug(f"Resp: {resp}")
|
||||
logger.debug(f"{resp.content}")
|
||||
return resp
|
||||
logger.debug(f"Resp: {resp}")
|
||||
logger.debug(f"{resp.content}")
|
||||
return resp
|
||||
|
||||
progress_dialog.Update(n, f"Uploading batch {n}/{len(chunked_files)}")
|
||||
p.update(n)
|
||||
#progress_dialog.Update(n, f"Uploading batch {n}/{len(chunked_files)}")
|
||||
|
||||
logger.debug(f"n: {n}")
|
||||
# try to upload the files
|
||||
resp = upload_files(files)
|
||||
if resp.status_code == 200:
|
||||
upload_file_list.extend(resp.json()["uploaded"])
|
||||
duplicate_file_list.extend(resp.json()["duplicates"])
|
||||
logger.debug(f"n: {n}")
|
||||
# try to upload the files
|
||||
resp = upload_files(files)
|
||||
if resp.status_code == 200:
|
||||
upload_file_list.extend(resp.json()["uploaded"])
|
||||
duplicate_file_list.extend(resp.json()["duplicates"])
|
||||
|
||||
continue
|
||||
continue
|
||||
|
||||
logger.debug(f"n: {n} fail")
|
||||
# try again if we fail
|
||||
resp = upload_files(files)
|
||||
if resp.status_code == 200:
|
||||
upload_file_list.extend(resp.json()["uploaded"])
|
||||
duplicate_file_list.extend(resp.json()["duplicates"])
|
||||
continue
|
||||
logger.debug(f"n: {n} fail")
|
||||
# try again if we fail
|
||||
resp = upload_files(files)
|
||||
if resp.status_code == 200:
|
||||
upload_file_list.extend(resp.json()["uploaded"])
|
||||
duplicate_file_list.extend(resp.json()["duplicates"])
|
||||
continue
|
||||
|
||||
progress_dialog.Destroy()
|
||||
#progress_dialog.Destroy()
|
||||
|
||||
print(upload_file_list)
|
||||
print(duplicate_file_list)
|
||||
@@ -1215,10 +1262,10 @@ class AnonGui(wx.App):
|
||||
@app.callback(invoke_without_command=True)
|
||||
def runGUI(
|
||||
ctx: typer.Context,
|
||||
#input_dir: Path = "C:\\Temp\\",
|
||||
input_dir: Path = "/home/ross/temp/in/",
|
||||
#output_dir: Path = "C:\\temp_upload\\",
|
||||
output_dir: Path = "/home/ross/temp/out/",
|
||||
input_dir: Path = "C:\\Temp\\",
|
||||
#input_dir: Path = "/home/ross/temp/in/",
|
||||
output_dir: Path = "C:\\temp_upload\\",
|
||||
#output_dir: Path = "/home/ross/temp/out/",
|
||||
silent_fail: bool = False,
|
||||
clear_files: bool = True,
|
||||
clear_files_on_close: bool = True,
|
||||
|
||||
+3
-12
@@ -1,33 +1,24 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
block_cipher = None
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['anon_gui.py'],
|
||||
pathex=[],
|
||||
#binaries=[(r"C:\Users\krugerro\Desktop\rad_tools\.venv\Lib\site-packages\pywin32_system32\pythoncom311.dll", "."),
|
||||
#(r"C:\Users\krugerro\Desktop\rad_tools\.venv\Lib\site-packages\pywin32_system32\pywintypes311.dll", "."),
|
||||
#],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='anon_gui',
|
||||
@@ -37,7 +28,7 @@ exe = EXE(
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
|
||||
+2
-1
@@ -8,4 +8,5 @@ requests
|
||||
zmq
|
||||
blake3
|
||||
loguru
|
||||
dicom2jp: boolg
|
||||
dicom2jpg
|
||||
pyinstaller
|
||||
Reference in New Issue
Block a user