lots of fixes

This commit is contained in:
Ross Kruger
2024-02-19 09:44:05 +00:00
parent e5ae513cce
commit 1e3318dfd6
6 changed files with 179 additions and 129 deletions
+6 -1
View File
@@ -4,4 +4,9 @@
logs/*
.pyc
__pycache__/*
__pycache__/*
build
dist
*.build
+6
View File
@@ -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" %*
BIN
View File
Binary file not shown.
+162 -115
View File
@@ -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
View File
@@ -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
View File
@@ -8,4 +8,5 @@ requests
zmq
blake3
loguru
dicom2jp: boolg
dicom2jpg
pyinstaller