194 lines
5.3 KiB
Python
194 lines
5.3 KiB
Python
import webview
|
|
import time
|
|
|
|
import sys
|
|
|
|
from datauri import DataURI
|
|
|
|
from pathlib import Path
|
|
|
|
import pydicom
|
|
import dicognito.anonymizer
|
|
|
|
import typer
|
|
from typing import List
|
|
|
|
from watchdog.observers import Observer
|
|
|
|
# from watchdog.events import LoggingEventHandler
|
|
from watchdog.events import PatternMatchingEventHandler
|
|
|
|
|
|
anonymizer = dicognito.anonymizer.Anonymizer()
|
|
|
|
app = typer.Typer()
|
|
|
|
|
|
def anonymize_file(filepath):
|
|
try:
|
|
with pydicom.dcmread(filepath) as dataset:
|
|
anonymizer.anonymize(dataset)
|
|
p = Path(filepath)
|
|
new_filename = Path(p.parent, f"{p.stem}_anon{p.suffix}")
|
|
dataset.save_as(new_filename)
|
|
return new_filename
|
|
except:
|
|
# Cannot anonymise so just return the same path
|
|
return filepath
|
|
|
|
|
|
class PythonJavascriptApi:
|
|
def __init__(self):
|
|
self.cancel_heavy_stuff_flag = False
|
|
|
|
def init(self):
|
|
response = {"message": "Hello from Python {0}".format(sys.version)}
|
|
return response
|
|
|
|
def sayHelloTo(self, name):
|
|
response = {"message": "Hello {0}!".format(name)}
|
|
return response
|
|
|
|
def error(self):
|
|
raise Exception("This is a Python exception")
|
|
|
|
|
|
class Watcher:
|
|
def __init__(self, window, anonymise: bool) -> None:
|
|
self.window = window
|
|
self.anonymise = anonymise
|
|
|
|
def on_created(self, event):
|
|
print(f"hey, {event.src_path} has been created!")
|
|
path = event.src_path
|
|
if self.anonymise:
|
|
path = anonymize_file(path)
|
|
|
|
try:
|
|
file_uri = DataURI.from_file(path)
|
|
except FileNotFoundError:
|
|
print("File deleted...")
|
|
return
|
|
|
|
file_name = Path(path).name
|
|
self.injectFile(file_uri, file_name)
|
|
|
|
def on_deleted(self, event):
|
|
print(f"what the f**k! Someone deleted {event.src_path}!")
|
|
|
|
def on_modified(self, event):
|
|
print(f"hey buddy, {event.src_path} has been modified")
|
|
|
|
def on_moved(self, event):
|
|
print(f"ok ok ok, someone moved {event.src_path} to {event.dest_path}")
|
|
|
|
def injectFile(self, file_uri: DataURI, file_name: str):
|
|
current_url = webview.windows[0].get_current_url()
|
|
if current_url == "https://www.penracourses.org.uk/rapids/create/":
|
|
print(f"inject {file_name}")
|
|
self.window.evaluate_js(
|
|
f"""
|
|
function urltoFile(url, filename, mimeType){{
|
|
return (fetch(url)
|
|
.then(function(res){{ return res.arrayBuffer(); }})
|
|
.then(function(buf){{return new File([buf], filename,{{type:mimeType}});}})
|
|
);
|
|
}}
|
|
|
|
|
|
$(document).ready(() => {{
|
|
//Usage example:
|
|
urltoFile('{file_uri}', '{file_name}', '{file_uri.mimetype}')
|
|
.then(function(file){{
|
|
|
|
console.log(file);
|
|
|
|
//inputs = $("#rapid-form input[type=file][id^=id_images-]");
|
|
inputs = extendInputs(1);
|
|
console.log(inputs);
|
|
el = inputs.get(0);
|
|
console.log(el);
|
|
|
|
let dT = new DataTransfer();
|
|
dT.clearData();
|
|
dT.items.add(file);
|
|
|
|
el.files = dT.files;
|
|
|
|
// Manually fire the change event (qt doesn't seem to...)
|
|
$(el).change();
|
|
|
|
|
|
}});
|
|
|
|
}});
|
|
"""
|
|
)
|
|
|
|
|
|
@app.command()
|
|
def anatomy(filepath: str):
|
|
raise NotImplementedError
|
|
|
|
|
|
@app.command()
|
|
def rapid(watch_path: Path = "/home/ross/watch", anonymise: bool = True):
|
|
|
|
api = PythonJavascriptApi()
|
|
window = webview.create_window(
|
|
"Upload Rapid", "https://www.penracourses.org.uk/rapids/create/", js_api=api
|
|
)
|
|
|
|
# def on_loaded():
|
|
# print('DOM is ready')
|
|
# current_url = webview.windows[0].get_current_url()
|
|
|
|
# if current_url == "https://www.penracourses.org.uk/rapids/create/":
|
|
# #window.evaluate_js("alert('tent')")
|
|
|
|
# for file_uri, file_name in uri_name_list:
|
|
# #time.sleep(2)
|
|
|
|
# ## unsubscribe event listener
|
|
# #webview.windows[0].loaded -= on_loaded
|
|
# #webview.windows[0].load_url('https://google.com')
|
|
|
|
# window.loaded += on_loaded
|
|
# window = upload_rapid(["/home/ross/Downloads/DICOM CT/DICOM CXR/STD1/SER1/CXR.dcm"])
|
|
|
|
patterns = ["*"]
|
|
ignore_patterns = ["*anon*"]
|
|
ignore_directories = False
|
|
case_sensitive = True
|
|
my_event_handler = PatternMatchingEventHandler(
|
|
patterns, ignore_patterns, ignore_directories, case_sensitive
|
|
)
|
|
|
|
watcher = Watcher(window, anonymise)
|
|
my_event_handler.on_created = watcher.on_created
|
|
my_event_handler.on_deleted = watcher.on_deleted
|
|
my_event_handler.on_modified = watcher.on_modified
|
|
my_event_handler.on_moved = watcher.on_moved
|
|
my_observer = Observer()
|
|
|
|
Path(watch_path).mkdir(parents=True, exist_ok=True)
|
|
my_observer.schedule(my_event_handler, watch_path, recursive=True)
|
|
|
|
my_observer.start()
|
|
# try:
|
|
# while True:
|
|
# time.sleep(1)
|
|
# except KeyboardInterrupt:
|
|
# my_observer.stop()
|
|
# my_observer.join()
|
|
webview.start(None, window, debug=True, gui="qt")
|
|
|
|
|
|
|
|
# f = "/media/ross/f6200b79-c343-4882-a245-28fc06d43006/Downloads/temp/breasts.jpg"
|
|
f = "/home/ross/Downloads/DICOM CT/DICOM CXR/STD1/SER1/CXR.dcm"
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app()
|