Merge branch 'cleanup_empty_scans' into 'v3'
Added purge_empty_scans() method Closes #370 See merge request openflexure/openflexure-microscope-server!257
This commit is contained in:
commit
c793620fcd
2 changed files with 58 additions and 9 deletions
|
|
@ -588,6 +588,9 @@ class SmartScanThing(Thing):
|
|||
self._return_to_starting_position()
|
||||
self._perform_final_stitch()
|
||||
|
||||
# Remove any scan folders containing zero images
|
||||
self.purge_empty_scans(logger=self._scan_logger)
|
||||
|
||||
@_scan_running
|
||||
def _main_scan_loop(self):
|
||||
"""
|
||||
|
|
@ -868,22 +871,26 @@ class SmartScanThing(Thing):
|
|||
404: {"description": "Scan not found"},
|
||||
},
|
||||
)
|
||||
def delete_scan(self, scan_name: str) -> None:
|
||||
"""Delete all files from a scan.
|
||||
def delete_scan(self, scan_name: str, logger: InvocationLogger) -> None:
|
||||
"""Delete the folder for the specified scan.
|
||||
|
||||
This endpoint allows scans to be deleted from disk.
|
||||
|
||||
Takes the scan name to delete, and the Invocation Logger
|
||||
"""
|
||||
path = os.path.join(self.base_scan_dir, scan_name)
|
||||
if not os.path.isdir(path):
|
||||
print(f"can't find {path}")
|
||||
raise HTTPException(404, "Scan not found")
|
||||
shutil.rmtree(path)
|
||||
logger.info(f"can't find {path}")
|
||||
raise HTTPException(400, "Scan not found")
|
||||
deleted_scan_success = self._delete_scan(path, logger)
|
||||
if not deleted_scan_success:
|
||||
raise HTTPException(400, "Couldn't delete scan, check log for details")
|
||||
|
||||
@fastapi_endpoint(
|
||||
"delete",
|
||||
"scans",
|
||||
)
|
||||
def delete_all_scans(self) -> None:
|
||||
def delete_all_scans(self, logger: InvocationLogger) -> None:
|
||||
"""Delete all the scans on the microscope
|
||||
|
||||
**This will irreversibly remove all scanned data from the
|
||||
|
|
@ -891,7 +898,20 @@ class SmartScanThing(Thing):
|
|||
Use with extreme caution.
|
||||
"""
|
||||
for scan in self.scans:
|
||||
self.delete_scan(scan.name)
|
||||
path = os.path.join(self.base_scan_dir, scan.name)
|
||||
self._delete_scan(path, logger)
|
||||
|
||||
@thing_action
|
||||
def _delete_scan(self, scan_path, logger: InvocationLogger) -> bool:
|
||||
try:
|
||||
shutil.rmtree(scan_path)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
"Attempted to delete scan " + scan_path + ", which failed."
|
||||
" Server sent response" + str(e)
|
||||
)
|
||||
return False
|
||||
|
||||
@property
|
||||
def latest_preview_stitch_path(self):
|
||||
|
|
@ -1179,3 +1199,26 @@ class SmartScanThing(Thing):
|
|||
"""List the relative paths of all files and folders in the zip folder specified"""
|
||||
scan_zip = zipfile.ZipFile(zip_path)
|
||||
return [os.path.normpath(i) for i in scan_zip.namelist()]
|
||||
|
||||
@thing_action
|
||||
def purge_empty_scans(self, logger: InvocationLogger) -> None:
|
||||
"""
|
||||
Delete all scan folders containing no images at the top level
|
||||
"""
|
||||
scan_list = self.scans
|
||||
|
||||
# Filter out scans with no top level files, ignoring JSON files
|
||||
# JSON is ignored as it's created before any images are captured
|
||||
for scan in scan_list:
|
||||
scan_folder = os.path.join(self.base_scan_dir, scan.name, IMG_DIR_NAME)
|
||||
images_found = False
|
||||
for fname in os.listdir(scan_folder):
|
||||
fpath = os.path.join(scan_folder, fname)
|
||||
if os.path.isfile(fpath) and IMAGE_REGEX.search(fname):
|
||||
images_found = True
|
||||
# break as soon as an image is found.
|
||||
break
|
||||
|
||||
if not images_found:
|
||||
path = os.path.join(self.base_scan_dir, scan.name)
|
||||
self._delete_scan(path, logger)
|
||||
|
|
|
|||
|
|
@ -144,10 +144,16 @@ Vue.mixin({
|
|||
if (error.response) {
|
||||
// If the response is a nicely formatted JSON response from the server
|
||||
if (error.response.data.message) {
|
||||
return `${error.response.status}: ${error.response.data.message}`;
|
||||
return `${error.response.data.message}`;
|
||||
}
|
||||
if (error.response.data.detail) {
|
||||
return `${error.response.data.detail}`;
|
||||
}
|
||||
// If the response is just some generic error response
|
||||
return `${error.response.status}: ${error.response.data}`;
|
||||
if (error.response.data){
|
||||
return `${error.response.data}`;
|
||||
}
|
||||
return `${error.response}`;
|
||||
}
|
||||
// If we have an error object with a message, use that
|
||||
if (error.message) return `${error.message}`;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue