Skip to content

Commit

Permalink
Implement curry_name_mapper
Browse files Browse the repository at this point in the history
  • Loading branch information
jennydaman committed Jul 25, 2023
1 parent c0acdf4 commit d1cdd84
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 4 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

setup(
name="chris_plugin",
version="0.2.0a1",
version="0.2.0",
packages=find_packages(where="src"),
package_dir={"": "src", "chris_plugin": "src/chris_plugin"},
url="https://github.com/FNNDSC/chris_plugin",
Expand Down
4 changes: 2 additions & 2 deletions src/chris_plugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ def main(_, input_dir, output_dir):
"""

from chris_plugin.chris_plugin import chris_plugin
from chris_plugin.mapper import PathMapper
from chris_plugin.mapper import PathMapper, curry_name_mapper
import chris_plugin.types as types

__docformat__ = "numpy"

__all__ = ["chris_plugin", "PathMapper", "types"]
__all__ = ["chris_plugin", "PathMapper", "curry_name_mapper", "types"]
64 changes: 64 additions & 0 deletions src/chris_plugin/mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

NameMapper = Callable[[Path, Path], Path]


# Private Helpers
########

Expand All @@ -24,6 +25,69 @@ def append_suffix(input_file: Path, output_dir: Path) -> Path:
return append_suffix


def curry_name_mapper(output_template: str) -> Callable[[Path, Path], Path]:
"""
A helper function which creates a function that is a suitable value for
the `PathMapper.name_mapper` arguments to `PathMapper` constructor functions.
Woah! Sorry, I don't really know how better to describe it. Please see the
example, or better yet, my tests.
Examples
--------
A common use case is for a *ChRIS* plugin to have the option to give an output
file name template. For example:
```shell
$ myplugin --output-template 'yummy_{}_processed.txt' inputdir/ outputdir/
inputdir/fruits/pear.dat -> outputdir/fruits/yummy_pear_processed.txt
inputdir/fruits/apple.dat -> outputdir/fruits/yummy_apple_processed.txt
```
This can be achieved by:
```python
from argparse import ArgumentParser
import shutil
from chris_plugin import chris_plugin, PathMapper, curry_name_mapper
parser = ArgumentParser()
parser.add_argument('-o', '--output-template', type=str,
default='copied_{}.dat',
help='output file name template')
@chris_plugin(parser)
def main(options, inputdir, outputdir):
name_mapper = curry_name_mapper(options.output_template)
mapper = PathMapper.file_mapper(inputdir, outputdir, name_mapper=name_mapper)
for input_file, output_file in mapper:
shutil.copy(input_file, output_file)
```
Parameters
----------
output_template: str
output file template
Returns
-------
name_mapper
A function which can be given to `PathMapper` as the parameter for `name_mapper`.
"""

def name_mapper(rel_path: Path, output_dir: Path) -> Path:
# if output file template ends with {}, then keep file extension
if output_template.endswith("{}"):
template = output_template[:-2] + rel_path.name
else: # otherwise, drop file extension
template = output_template
name = template.replace("{}", rel_path.stem).replace("{{}}", "{}")
return output_dir / rel_path.with_name(name)

return name_mapper


# Public Classes
########

Expand Down
16 changes: 15 additions & 1 deletion tests/test_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pytest

from chris_plugin.mapper import _curry_suffix, PathMapper
from chris_plugin.mapper import _curry_suffix, PathMapper, curry_name_mapper


def test_suffix():
Expand Down Expand Up @@ -117,3 +117,17 @@ def test_dir_mapper_deep(dirs: Tuple[Path, Path], dirs_to_create: List[str]):
input_dir, output_dir = dirs
mapper = PathMapper.dir_mapper_deep(input_dir, output_dir)
assert_input_names(mapper, {"lettuce", "pancake", "waffle"})


@pytest.mark.parametrize(
"template, expected",
[
("prefix_{}", "outgoing/rel/prefix_fruity.dat"),
("{}.suffix", "outgoing/rel/fruity.suffix"),
("wehaveyou_{}_surrounded", "outgoing/rel/wehaveyou_fruity_surrounded"),
],
)
def test_curry_name_mapper(template: str, expected: str):
output_dir = Path("outgoing")
name_mapper = curry_name_mapper(template)
assert name_mapper(Path("rel/fruity.dat"), output_dir) == Path(expected)

0 comments on commit d1cdd84

Please sign in to comment.