Skip to content

Commit

Permalink
feat(scripts): add scripts to work with cope binary
Browse files Browse the repository at this point in the history
  • Loading branch information
mgeerdsen committed May 29, 2024
1 parent 294083f commit 5c6a2c5
Show file tree
Hide file tree
Showing 3 changed files with 219 additions and 0 deletions.
50 changes: 50 additions & 0 deletions install/cope/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

# COPE scripts

## EIP extraction

The script `eip_prepare_for_cope.py` extracts EIP files in a source directory to a target directory. It renames a specific subdirectory (`CaptureOne/Settings153` to `CaptureOne/Settings131`) and moves the EIP files into the `_raw` image directory.

## Usage

```
usage: eip_prepare_for_cope.py [-h] -s SOURCE -t TARGET
options:
-h, --help show this help message and exit
-s SOURCE, --source SOURCE
Source directory
-t TARGET, --target TARGET
Target directory
```

in Goobi workflow this can be integrated in a script step like this:

```shell
/opt/digiverso/goobi/scripts/eip_prepare_for_cope.py -s {origpath} -t {origpath}
```

## COPE conversion

The script `cope_folder.py` converts IIQ files from the source directory and uses COPE to convert them to tiff files located in the target directory. Optionally the given resolution value will be used.

## Usage

```
usage: cope_folder.py [-h] -s SOURCE -t TARGET [-r RESOLUTION]
options:
-h, --help show this help message and exit
-s SOURCE, --source SOURCE
-t TARGET, --target TARGET
-r RESOLUTION, --resolution RESOLUTION
```

The path to the cope binary can be given by an environment variable named `COPE_PATH`.

In Goobi workflow a script step in the external queue can be used to run the script on a Windows workernode like this:

```CMD
C:\Windows\py.exe D:\intranda\cope_folder.py -s "//mediaSMB-isilonArchive/GoobiMetadata/{s3_origpath}" -t "//mediaSMB-isilonArchive/GoobiMetadata/{s3_origpath}" -r "{process.File Resolution}"
```

104 changes: 104 additions & 0 deletions install/cope/cope_folder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/usr/bin/env python3

import logging
import os
import shutil
import subprocess
from argparse import ArgumentParser
from pathlib import Path

loglevel = (os.environ.get('PYTHON_LOGLEVEL') or "DEBUG").upper()
numeric_level = getattr(logging, loglevel.upper(), None)
logging.basicConfig(
format='%(asctime)s %(levelname)-8s %(message)s', level=numeric_level)

file_name_pattern = "*.IIQ"
path_cope = (os.environ.get('COPE_PATH') or Path(
"C:/cope.Win.13.1.15-name_cope131/COPE/Bin/COPE.exe"))

cope_options = ["-bits=8"]


def find_files(root_dir: Path, file_name_pattern: str) -> list[list]:
"""find files matching file_name_pattern in direct subdirectories of root_dir
Args:
root_dir (Path): top level directory to perform search in
file_name_pattern (str): globbing expression to match for
Returns:
list[list]: a list of lists with the filename and the parent directory basename of matching files
"""
found_files = []
for file in Path(root_dir).glob("*/"+file_name_pattern):
found_files.append([file, file.parent.stem])
return (found_files)


def get_parser():
"""provides argument parser"""
parser = ArgumentParser()
parser.add_argument("-s", "--source", dest="source",
required=True, type=str)
parser.add_argument("-t", "--target", dest="target",
required=True, type=str)
parser.add_argument("-r", "--resolution", dest="resolution",
required=False, type=int)
return parser


if __name__ == "__main__":
parser = get_parser()
args = parser.parse_args()

sourcedir = Path(args.source)
targetdir = Path(args.target)
resolution = args.resolution

logging.debug(f"path to cope: {path_cope}")
logging.debug(f"source directory: {sourcedir}")
logging.debug(f"target directory: {targetdir}")

if resolution:
logging.debug(f"resolution: {resolution}")
cope_options.append(f"-resolution={resolution}")

if not os.path.isdir(sourcedir):
logging.error("source directory does not exist")
exit(1)

if not os.path.isdir(targetdir):
os.mkdir(targetdir)
logging.info("target directory created, as it did not exist")

logging.info("start processing...")
files = find_files(sourcedir, file_name_pattern)

if not files:
logging.info("no matching files found in source directory")

for file, base in files:
target = Path(targetdir) / (base + ".tif")
logging.info(f"processing {file}")

cope_command = [Path(path_cope), file, target] + cope_options

logging.debug(f"running {cope_command}")

# execute cope
try:
subprocess.run(cope_command, check=True)
except FileNotFoundError:
logging.error(f"cope executable was not found: {path_cope}")
exit(1)
except Exception as err:
logging.error(f"Unexpected {err=}, {type(err)=}")
raise

# cope does not appear to make much use of exit codes, thus we check the existence of the expected tiff file here
if not target.is_file():
logging.error(f"tiff file expected but not found: {target}")
exit(1)
else:
logging.debug(f"removing source package {target.with_suffix('')}")
shutil.rmtree(target.with_suffix(''))
65 changes: 65 additions & 0 deletions install/cope/eip_prepare_for_cope.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python3

# This script extracts eip files in a source directory to a target directory, renames a specific subdirectory and moves the original eip files

import os
import shutil
from argparse import ArgumentParser
from pathlib import Path


def extract_and_rename_eip(source_dir, target_dir):
# Check if source directory exists
if not os.path.isdir(source_dir):
print("Source directory does not exist")
exit(1)

# Create target directory if it does not exist
os.makedirs(target_dir, exist_ok=True)

if source_dir.name.endswith("_master"):
raw_directory = Path.joinpath(
source_dir.parent, source_dir.name.replace("_master", "_raw"))
os.makedirs(raw_directory, exist_ok=True)

for filename in os.listdir(source_dir):
if filename.endswith(".eip"):
file_path = os.path.join(source_dir, filename)
if os.path.isfile(file_path):
# Unzip eip to target directory
unzip_dir = os.path.join(
target_dir, os.path.splitext(filename)[0])
shutil.unpack_archive(filename=file_path,
extract_dir=unzip_dir, format="zip")

capture_one_dir = os.path.join(unzip_dir, "CaptureOne")
settings_old = os.path.join(capture_one_dir, "Settings153")
settings_new = os.path.join(capture_one_dir, "Settings131")

# Check if CaptureOne directory exists
if not os.path.isdir(capture_one_dir):
print(f"{capture_one_dir} does not exist")
exit(1)

# Rename setting directory to matching version for cope
if os.path.isdir(settings_old):
os.rename(settings_old, settings_new)

os.rename(file_path, Path.joinpath(raw_directory, filename))


def get_parser():
"""provides argument parser"""
parser = ArgumentParser()
parser.add_argument("-s", "--source", dest="source",
required=True, type=str, help="Source directory")
parser.add_argument("-t", "--target", dest="target",
required=True, type=str, help="Target directory")
return parser


if __name__ == "__main__":
parser = get_parser()
args = parser.parse_args()

extract_and_rename_eip(Path(args.source), Path(args.target))

0 comments on commit 5c6a2c5

Please sign in to comment.