Download stitched image of scan (if present)
* Docstring for download stitch * use global STITCH_SUFFIX
This commit is contained in:
parent
62065dc385
commit
ff43deae36
3 changed files with 91 additions and 25 deletions
|
|
@ -5,7 +5,7 @@ Currently it handles scan getting information from a information from a scan dir
|
||||||
eventually is should handle all the file system operation for smart_scan.
|
eventually is should handle all the file system operation for smart_scan.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional, Literal
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
|
|
@ -13,6 +13,7 @@ import zipfile
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
STITCH_SUFFIX = "_stitched.jpg"
|
||||||
IMG_DIR_NAME = "images"
|
IMG_DIR_NAME = "images"
|
||||||
IMAGE_REGEX = re.compile(r"-?[0-9]+_-?[0-9]+\.jpe?g$")
|
IMAGE_REGEX = re.compile(r"-?[0-9]+_-?[0-9]+\.jpe?g$")
|
||||||
SCAN_ZERO_PAD_DIGITS = 4
|
SCAN_ZERO_PAD_DIGITS = 4
|
||||||
|
|
@ -88,7 +89,7 @@ class ScanDirectoryManager:
|
||||||
"""Return the file path for the file within a scan directory
|
"""Return the file path for the file within a scan directory
|
||||||
|
|
||||||
If check_exists is True, None is returned if the file does not exist. If False
|
If check_exists is True, None is returned if the file does not exist. If False
|
||||||
then the path is returned anway
|
then the path is returned anyway
|
||||||
"""
|
"""
|
||||||
file_path = os.path.join(self.img_dir_for(scan_name), filename)
|
file_path = os.path.join(self.img_dir_for(scan_name), filename)
|
||||||
if check_exists:
|
if check_exists:
|
||||||
|
|
@ -96,6 +97,13 @@ class ScanDirectoryManager:
|
||||||
return None
|
return None
|
||||||
return file_path
|
return file_path
|
||||||
|
|
||||||
|
def get_final_stitch(self, scan_name: str) -> Optional[str]:
|
||||||
|
"""Return the file path for the final stitch.
|
||||||
|
|
||||||
|
If no final stitch is found, return None
|
||||||
|
"""
|
||||||
|
return ScanDirectory(scan_name, self.base_dir).get_final_stitch()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def all_scans(self) -> list[str]:
|
def all_scans(self) -> list[str]:
|
||||||
"""Return a list of the scan names in the base directory"""
|
"""Return a list of the scan names in the base directory"""
|
||||||
|
|
@ -242,25 +250,55 @@ class ScanDirectory:
|
||||||
return []
|
return []
|
||||||
return os.listdir(self.images_dir)
|
return os.listdir(self.images_dir)
|
||||||
|
|
||||||
|
def _find_files(
|
||||||
|
self, file_types=Literal["all", "scan_images", "stitches", "dzi"]
|
||||||
|
) -> tuple[list[str], list[str], list[str]] | list[str]:
|
||||||
|
folder_contents = self.get_scan_files()
|
||||||
|
|
||||||
|
# Return empty lists if no folder contents.
|
||||||
|
if not folder_contents:
|
||||||
|
if file_types == "all":
|
||||||
|
return [], [], []
|
||||||
|
return []
|
||||||
|
|
||||||
|
if file_types in ["all", "scan_images"]:
|
||||||
|
scan_images = [i for i in folder_contents if IMAGE_REGEX.search(i)]
|
||||||
|
if file_types == "scan_images":
|
||||||
|
return scan_images
|
||||||
|
|
||||||
|
if file_types in ["all", "stitches"]:
|
||||||
|
stitches = [i for i in folder_contents if i.endswith("_stitched.jpg")]
|
||||||
|
if file_types == "stitches":
|
||||||
|
return stitches
|
||||||
|
|
||||||
|
if file_types in ["all", "dzi"]:
|
||||||
|
dzi_files = [i for i in folder_contents if i.endswith("dzi")]
|
||||||
|
if file_types == "dzi":
|
||||||
|
return dzi_files
|
||||||
|
|
||||||
|
return scan_images, stitches, dzi_files
|
||||||
|
|
||||||
|
def get_final_stitch(self) -> Optional[str]:
|
||||||
|
"""Return the file path for the final stitch.
|
||||||
|
|
||||||
|
If no final stitch is found, return None
|
||||||
|
"""
|
||||||
|
stitches = self._find_files("stitches")
|
||||||
|
if not stitches:
|
||||||
|
return None
|
||||||
|
return stitches[0]
|
||||||
|
|
||||||
def get_modified_time(self) -> float:
|
def get_modified_time(self) -> float:
|
||||||
"""Return the modified time of the directory"""
|
"""Return the modified time of the directory"""
|
||||||
return max(os.stat(root).st_mtime for root, _, _ in os.walk(self.dir_path))
|
return max(os.stat(root).st_mtime for root, _, _ in os.walk(self.dir_path))
|
||||||
|
|
||||||
def scan_info(self):
|
def scan_info(self):
|
||||||
"""Return the information for the scan directory as a ScanInfo object"""
|
"""Return the information for the scan directory as a ScanInfo object"""
|
||||||
folder_contents = self.get_scan_files()
|
|
||||||
if folder_contents:
|
|
||||||
scan_images = [i for i in folder_contents if IMAGE_REGEX.search(i)]
|
|
||||||
stitches = [i for i in folder_contents if i.endswith("_stitched.jpg")]
|
|
||||||
dzi_files = [i for i in folder_contents if i.endswith("dzi")]
|
|
||||||
|
|
||||||
number_of_images = len(scan_images)
|
scan_images, stitches, dzi_files = self._find_files("all")
|
||||||
stitch_available = len(stitches) > 0
|
number_of_images = len(scan_images)
|
||||||
dzi = None if not dzi_files else str(dzi_files[0])
|
stitch_available = len(stitches) > 0
|
||||||
else:
|
dzi = None if not dzi_files else str(dzi_files[0])
|
||||||
number_of_images = 0
|
|
||||||
stitch_available = False
|
|
||||||
dzi = None
|
|
||||||
|
|
||||||
return ScanInfo(
|
return ScanInfo(
|
||||||
name=self.name,
|
name=self.name,
|
||||||
|
|
|
||||||
|
|
@ -666,6 +666,30 @@ class SmartScanThing(Thing):
|
||||||
"""
|
"""
|
||||||
return self._scan_dir_manager.all_scans_info()
|
return self._scan_dir_manager.all_scans_info()
|
||||||
|
|
||||||
|
@fastapi_endpoint(
|
||||||
|
"get",
|
||||||
|
"get_stitch/{scan_name}",
|
||||||
|
responses={
|
||||||
|
200: {
|
||||||
|
"description": "Successfully downloading file",
|
||||||
|
"content": {"*/*": {}},
|
||||||
|
},
|
||||||
|
403: {"description": "Filename not permitted"},
|
||||||
|
404: {"description": "File not found"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
def get_stitch_file(self, scan_name: str) -> FileResponse:
|
||||||
|
"""Return the stitched image corresponding to a given scan name, if it exists.
|
||||||
|
|
||||||
|
Will only return a file ending in suffix STITCH_SUFFIX
|
||||||
|
Note: when downloading this, the default filename will be `scan_name`.jpeg"""
|
||||||
|
|
||||||
|
stitch_path = self._scan_dir_manager.get_final_stitch(scan_name)
|
||||||
|
|
||||||
|
if stitch_path is None:
|
||||||
|
raise HTTPException(404, "File not found")
|
||||||
|
return FileResponse(stitch_path)
|
||||||
|
|
||||||
@fastapi_endpoint(
|
@fastapi_endpoint(
|
||||||
"delete",
|
"delete",
|
||||||
"scans/{scan_name}",
|
"scans/{scan_name}",
|
||||||
|
|
|
||||||
|
|
@ -97,17 +97,13 @@
|
||||||
@error="modalError"
|
@error="modalError"
|
||||||
class="uk-button uk-width-1-2"
|
class="uk-button uk-width-1-2"
|
||||||
/>
|
/>
|
||||||
<action-button
|
<a
|
||||||
thing="smart_scan"
|
class="uk-button uk-button-primary uk-width-1-2"
|
||||||
action="download_zip"
|
:class="item.stitch_available ? '' : 'disabled'"
|
||||||
submit-label="Download Stitch"
|
:href="downloadStitchFile( item.name )"
|
||||||
:can-terminate="false"
|
download
|
||||||
:submit-data="{ scan_name: item.name }"
|
>Download Stitch</a
|
||||||
:button-primary="true"
|
>
|
||||||
@response="downloadZipFile"
|
|
||||||
@error="modalError"
|
|
||||||
class="uk-button uk-width-1-2"
|
|
||||||
/>
|
|
||||||
<button
|
<button
|
||||||
class="uk-button uk-button-default uk-width-1-1"
|
class="uk-button uk-button-default uk-width-1-1"
|
||||||
@click="deleteScan(item.name)"
|
@click="deleteScan(item.name)"
|
||||||
|
|
@ -231,6 +227,9 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
downloadStitchFile: function(name) {
|
||||||
|
return `${this.$store.getters.baseUri}/smart_scan/get_stitch/${name}`;
|
||||||
|
},
|
||||||
thumbnailPath(scan_name) {
|
thumbnailPath(scan_name) {
|
||||||
return (
|
return (
|
||||||
`${this.$store.getters.baseUri}/smart_scan/scans/stitched_thumbnail.jpg?scan_name=` +
|
`${this.$store.getters.baseUri}/smart_scan/scans/stitched_thumbnail.jpg?scan_name=` +
|
||||||
|
|
@ -393,4 +392,9 @@ ul {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.disabled {
|
||||||
|
pointer-events: none;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue