Skip to content

Commit

Permalink
feat: add new lib_path argument to fmt_item_path
Browse files Browse the repository at this point in the history
Allows specifying the library path the formatted path will be relative to.
  • Loading branch information
jtpavlock committed Nov 5, 2022
1 parent 6bbf445 commit 5ed5dc4
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 65 deletions.
40 changes: 25 additions & 15 deletions moe/plugins/move/move_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import shutil
from contextlib import suppress
from pathlib import Path
from typing import Callable, Union
from typing import Callable, Optional, Union

import dynaconf
import pluggy
Expand Down Expand Up @@ -90,18 +90,29 @@ def e_unique(extra: Extra) -> str:
########################################################################################
# Format paths
########################################################################################
def fmt_item_path(item: LibItem) -> Path:
"""Returns a formatted item path according to the user configuration."""
def fmt_item_path(item: LibItem, lib_path: Optional[Path] = None) -> Path:
"""Returns a formatted item path according to the user configuration.
Args:
item: Item whose path will be formatted.
lib_path: Optional library path the outputted path will be relative to. By
default, this will be the ``library_path`` setting in the config.
Returns:
A formatted path as defined by the ``{album/extra/track}_path`` config template
settings relative to ``lib_path``.
"""
log.debug(f"Formatting item path. [path={item.path}]")

lib_path = lib_path or Path(config.CONFIG.settings.library_path).expanduser()

if isinstance(item, Album):
new_path = _fmt_album_path(item)
new_path = _fmt_album_path(item, lib_path)
elif isinstance(item, Extra):
new_path = _fmt_extra_path(item)
elif isinstance(item, Track):
new_path = _fmt_track_path(item)
new_path = _fmt_extra_path(item, lib_path)
else:
raise NotImplementedError
assert isinstance(item, Track)
new_path = _fmt_track_path(item, lib_path)

if config.CONFIG.settings.move.asciify_paths:
new_path = Path(unidecode(str(new_path)))
Expand All @@ -110,25 +121,24 @@ def fmt_item_path(item: LibItem) -> Path:
return new_path


def _fmt_album_path(album: Album) -> Path:
def _fmt_album_path(album: Album, lib_path: Path) -> Path:
"""Returns a formatted album directory according to the user configuration."""
library_path = Path(config.CONFIG.settings.library_path).expanduser()
album_path = _eval_path_template(config.CONFIG.settings.move.album_path, album)

return library_path / album_path
return lib_path / album_path


def _fmt_extra_path(extra: Extra) -> Path:
def _fmt_extra_path(extra: Extra, lib_path: Path) -> Path:
"""Returns a formatted extra path according to the user configuration."""
album_path = _fmt_album_path(extra.album_obj)
album_path = _fmt_album_path(extra.album_obj, lib_path)
extra_path = _eval_path_template(config.CONFIG.settings.move.extra_path, extra)

return album_path / extra_path


def _fmt_track_path(track: Track) -> Path:
def _fmt_track_path(track: Track, lib_path: Path) -> Path:
"""Returns a formatted track path according to the user configuration."""
album_path = _fmt_album_path(track.album_obj)
album_path = _fmt_album_path(track.album_obj, lib_path)
track_path = _eval_path_template(config.CONFIG.settings.move.track_path, track)

return album_path / track_path
Expand Down
67 changes: 17 additions & 50 deletions tests/plugins/move/test_move_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ def test_e_unique(self):
########################################################################################
# Test format paths
########################################################################################
class TestReplaceChars:
"""Test replacing of illegal or unwanted characters in paths."""
class TestFmtItemPath:
"""Test `fmt_item_path()`."""

def test_replace_chars(self, tmp_config):
"""Replace all the defined illegal characters from any paths."""
Expand Down Expand Up @@ -112,12 +112,8 @@ def test_replace_chars(self, tmp_config):
for path in formatted_paths:
assert any(replacement == path.name for replacement in replacements)


class TestFmtAlbumPath:
"""Tests `fmt_item_path(album)`."""

@pytest.mark.usefixtures("_tmp_move_config")
def test_relative_to_lib_path(self):
def test_album_relative_to_lib_path(self):
"""The album path should be relative to the library path configuration."""
album = album_factory()
lib_path = Path(config.CONFIG.settings.library_path)
Expand All @@ -126,72 +122,43 @@ def test_relative_to_lib_path(self):

assert album_path.is_relative_to(lib_path)

def test_album_asciify_paths(self, tmp_config):
"""Paths should not contain unicode characters if `asciify_paths` is true."""
album = album_factory(title="café")
tmp_config(
settings="""
default_plugins = ["move"]
[move]
asciify_paths = true
"""
)

# assumes that an album's title will be part of the new path
assert str(moe_move.fmt_item_path(album)).isascii()


class TestFmtExtraPath:
"""Tests `fmt_item_path(extra)`."""

@pytest.mark.usefixtures("_tmp_move_config")
def test_relative_to_album(self):
def test_extra_relative_to_album(self):
"""The extra path should be relative to its album path."""
extra = extra_factory()
extra_path = moe_move.fmt_item_path(extra)

assert extra_path.is_relative_to(moe_move.fmt_item_path(extra.album_obj))

def test_extra_asciify_paths(self, tmp_config):
"""Paths should not contain unicode characters if `asciify_paths` is true."""
tmp_config(
settings="""
default_plugins = ["move"]
[move]
asciify_paths = true
"""
)
extra = extra_factory()

# test assumes that an extra's path name will be part of the new path
extra.path = extra.path.with_name("café")
assert str(moe_move.fmt_item_path(extra)).isascii()


class TestFmtTrackPath:
"""Tests `fmt_item_path(extra)`."""

@pytest.mark.usefixtures("_tmp_move_config")
def test_relative_to_album(self):
def test_track_relative_to_album(self):
"""The track path should be relative to its album path."""
track = track_factory()
track_path = moe_move.fmt_item_path(track)

assert track_path.is_relative_to(track.album_obj.path)

def test_extra_asciify_paths(self, tmp_config):
def test_asciify_paths(self, tmp_config):
"""Paths should not contain unicode characters if `asciify_paths` is true."""
album = album_factory(title="café")
tmp_config(
settings="""
default_plugins = ["move"]
[move]
asciify_paths = true
"""
)
track = track_factory(title="café")

# assumes that a track's title will be part of the new path
assert str(moe_move.fmt_item_path(track)).isascii()
# assumes that an album's title will be part of the new path
assert str(moe_move.fmt_item_path(album)).isascii()

@pytest.mark.usefixtures("_tmp_move_config")
def test_given_lib_path(self, tmp_path):
"""If provided, paths should be relative to ``lib_path``."""
track = track_factory()
track_path = moe_move.fmt_item_path(track, tmp_path)

assert track_path.is_relative_to(tmp_path)


########################################################################################
Expand Down

0 comments on commit 5ed5dc4

Please sign in to comment.