Skip to content

Commit

Permalink
Unify upload args with render args
Browse files Browse the repository at this point in the history
These commands always operate on the same set of files: my Reaper *projects*, not just arbitrary audio files, which probably wouldn't be in SoundCloud.

* Update test snapshot to better reflect my actual project file layout convention
  • Loading branch information
john-kurkowski committed Nov 14, 2023
1 parent 1e24551 commit 1606073
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 30 deletions.
84 changes: 66 additions & 18 deletions src/music/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def export(dst_dir: Path, files: list[Path]) -> None:
default=None,
flag_value=SongVersion.MAIN,
help=(
"Whether to render the main version. Defaults to rendering all versions,"
"Whether to include the main version. Defaults to including all versions,"
' unless one of the "--include-*" flags is set.'
),
type=SongVersion,
Expand All @@ -91,8 +91,8 @@ def export(dst_dir: Path, files: list[Path]) -> None:
default=None,
flag_value=SongVersion.INSTRUMENTAL,
help=(
"Whether to render the instrumental version. Rendering this version is skipped"
" if no vocals exist. Defaults to rendering all versions,"
"Whether to include the instrumental version. This version is skipped"
" if no vocals exist. Defaults to including all versions,"
' unless one of the "--include-*" flags is set.'
),
type=SongVersion,
Expand All @@ -102,8 +102,8 @@ def export(dst_dir: Path, files: list[Path]) -> None:
default=None,
flag_value=SongVersion.ACAPPELLA,
help=(
"Whether to render the a cappella version. Rendering this version is skipped if"
" no vocals exist. Defaults to rendering all versions, unless"
"Whether to include the a cappella version. This version is skipped if"
" no vocals exist. Defaults to including all versions, unless"
' one of the "--include-*" flags is set.'
),
type=SongVersion,
Expand Down Expand Up @@ -222,9 +222,41 @@ def tag(file: Path) -> None:

@cli.command()
@click.argument(
"files",
"project_dirs",
nargs=-1,
type=click.Path(exists=True, path_type=Path),
type=click.Path(dir_okay=True, exists=True, file_okay=False, path_type=Path),
)
@click.option(
"--include-main",
default=None,
flag_value=SongVersion.MAIN,
help=(
"Whether to include the main version. Defaults to including all versions,"
' unless one of the "--include-*" flags is set.'
),
type=SongVersion,
)
@click.option(
"--include-instrumental",
default=None,
flag_value=SongVersion.INSTRUMENTAL,
help=(
"Whether to include the instrumental version."
" Defaults to including all versions,"
' unless one of the "--include-*" flags is set.'
),
type=SongVersion,
)
@click.option(
"--include-acappella",
default=None,
flag_value=SongVersion.ACAPPELLA,
help=(
"Whether to include the a cappella version."
" Defaults to including all versions, unless"
' one of the "--include-*" flags is set.'
),
type=SongVersion,
)
@click.option(
"--oauth_token",
Expand All @@ -234,20 +266,36 @@ def tag(file: Path) -> None:
" SOUNDCLOUD_OAUTH_TOKEN."
),
)
def upload(files: list[Path], oauth_token: str) -> None:
"""Upload rendered output FILES to SoundCloud.
def upload(
project_dirs: list[Path],
include_main: SongVersion | None,
include_instrumental: SongVersion | None,
include_acappella: SongVersion | None,
oauth_token: str,
) -> None:
"""Upload rendered output of the PROJECT_DIRS Reaper projects to SoundCloud.
Defaults FILES to all rendered versions of the currently open project.
Defaults to uploading all rendered versions of the currently open project.
"""
if not project_dirs:
project_dirs = [Path(music.util.ExtendedProject().path)]

versions = {
version
for version in (include_main, include_instrumental, include_acappella)
if version
} or set(SongVersion)

files = [
fil
for project_dir in project_dirs
for version in versions
if (fil := project_dir / f"{version.name_for_project_dir(project_dir)}.wav")
and fil.exists()
]

if not files:
project = music.util.ExtendedProject()
project_dir = Path(project.path)
files = [
fil
for version in SongVersion
if (fil := project_dir / f"{version.name_for_project_dir(project_dir)}.wav")
and fil.exists()
]
raise click.UsageError("nothing to upload")

music.upload.main(oauth_token, files)

Expand Down
4 changes: 2 additions & 2 deletions tests/__snapshots__/test_upload.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
'https://some-url',
),
dict({
'data': "<_io.BufferedReader name='TMP_PATH_HERE/path/to/some project.wav'>",
'data': "<_io.BufferedReader name='TMP_PATH_HERE/path/to/some project/some project.wav'>",
'headers': dict({
'some-uploader-id': 'some-uploader-value',
}),
Expand Down Expand Up @@ -171,7 +171,7 @@
'https://some-url',
),
dict({
'data': "<_io.BufferedReader name='TMP_PATH_HERE/path/to/another project.wav'>",
'data': "<_io.BufferedReader name='TMP_PATH_HERE/path/to/another project/another project.wav'>",
'headers': dict({
'some-uploader-id': 'some-uploader-value',
}),
Expand Down
21 changes: 11 additions & 10 deletions tests/test_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ def requests_mocks() -> Iterator[RequestsMocks]:
def some_paths(tmp_path: Path) -> list[Path]:
"""Create some files to upload."""
some_paths = [
tmp_path / "path" / "to" / "some project.wav",
tmp_path / "path" / "to" / "another project.wav",
tmp_path / "path" / "to" / "some project" / "some project.wav",
tmp_path / "path" / "to" / "another project" / "another project.wav",
]
for path in some_paths:
path.parent.mkdir(parents=True, exist_ok=True)
path.parent.mkdir(parents=True)
path.write_text(f".wav content for {path.stem}")

return some_paths
Expand All @@ -66,11 +66,12 @@ def envvars(monkeypatch: pytest.MonkeyPatch) -> None:

def test_main_no_network_calls(some_paths: list[Path]) -> None:
"""Test that main network calls are blocked."""
out = CliRunner(mix_stderr=False).invoke(
upload, [str(path.resolve()) for path in some_paths]
)

assert isinstance(out.exception, pytest_socket.SocketBlockedError)
with pytest.raises(pytest_socket.SocketBlockedError):
CliRunner(mix_stderr=False).invoke(
upload,
[str(path.parent.resolve()) for path in some_paths],
catch_exceptions=False,
)


def test_main_tracks_not_found(
Expand All @@ -79,7 +80,7 @@ def test_main_tracks_not_found(
"""Test main when tracks are not found/matched in the upstream database."""
result = CliRunner(mix_stderr=False).invoke(
upload,
[str(path.resolve()) for path in some_paths],
[str(path.parent.resolve()) for path in some_paths],
)

assert result.exception == snapshot
Expand Down Expand Up @@ -150,7 +151,7 @@ def mock_post(url: str, *args: Any, **kwargs: Any) -> mock.Mock:
requests_mocks.post.side_effect = mock_post
result = CliRunner(mix_stderr=False).invoke(
upload,
[str(path.resolve()) for path in some_paths],
[str(path.parent.resolve()) for path in some_paths],
catch_exceptions=False,
)

Expand Down

0 comments on commit 1606073

Please sign in to comment.