Skip to content

Commit 5e3839d

Browse files
committed
feat: add overwrite argument to overwrite existing files
1 parent 94fc39b commit 5e3839d

File tree

2 files changed

+55
-8
lines changed

2 files changed

+55
-8
lines changed

moe_transcode/transcode_core.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ def add_config_validator(settings: dynaconf.base.LazySettings):
4141

4242

4343
def transcode(
44-
item: I, to_format: TranscodeFormat, out_path: Optional[Path] = None
44+
item: I,
45+
to_format: TranscodeFormat,
46+
out_path: Optional[Path] = None,
47+
overwrite: bool = False,
4548
) -> I:
4649
"""Transcodes a track or album to a specific format.
4750
@@ -51,6 +54,7 @@ def transcode(
5154
to_format: Format to transcode to.
5255
out_path: Path of the transcoded item. This defaults to the formatted path per
5356
the configuration relative to the ``transcode_path`` setting.
57+
overwrite: Whether or not to overwrite existing files.
5458
5559
Returns:
5660
The transcoded track or album.
@@ -62,23 +66,29 @@ def transcode(
6266
out_path = out_path or fmt_item_path(item, transcode_path)
6367

6468
if isinstance(item, Album):
65-
return _transcode_album(item, to_format, out_path)
66-
return _transcode_track(item, to_format, out_path)
69+
return _transcode_album(item, to_format, out_path, overwrite)
70+
return _transcode_track(item, to_format, out_path, overwrite)
6771

6872

69-
def _transcode_album(album: Album, to_format: TranscodeFormat, out_path: Path) -> Album:
73+
def _transcode_album(
74+
album: Album, to_format: TranscodeFormat, out_path: Path, overwrite: bool = False
75+
) -> Album:
7076
"""Transcodes an album to a specific format.
7177
7278
Args:
7379
album: Album to transcode. Must contain flacs only.
7480
to_format: Format to transcode to.
7581
out_path: Path of the transcoded album. This defaults to the formatted path per
76-
the configuration relative to the ``transcode_path`` setting.
82+
the configuration relative to the ``transcode_path`` setting. Track files
83+
within the album will not be renamed except for any file extension changes.
84+
overwrite: Whether or not to overwrite existing files.
7785
7886
Returns:
7987
The transcoded album.
8088
8189
Raises:
90+
FileExistsError: If ``overwrite`` is ``False`` and the output path for a track
91+
already exists.
8292
ValueError: ``album`` contains a non-supported audio format.
8393
"""
8494
log.debug(f"Transcoding album. [{album=!r}, {to_format=!r}, {out_path=!r}]")
@@ -110,44 +120,59 @@ def _transcode_album(album: Album, to_format: TranscodeFormat, out_path: Path) -
110120
return transcoded_album
111121

112122

113-
def _transcode_track(track: Track, to_format: TranscodeFormat, out_path: Path) -> Track:
123+
def _transcode_track(
124+
track: Track, to_format: TranscodeFormat, out_path: Path, overwrite: bool = False
125+
) -> Track:
114126
"""Transcodes a track to a specific format.
115127
116128
Args:
117129
track: Track to transcode. The track will only be transcoded if it is a flac.
118130
to_format: Format to transcode to.
119131
out_path: Path of the transcoded track. This defaults to the formatted path per
120132
the configuration relative to the ``transcode_path`` setting.
133+
overwrite: Whether or not to overwrite existing files.
121134
122135
Returns:
123136
The transcoded track.
124137
125138
Raises:
139+
FileExistsError: If ``out_path`` already exists and ``overwrite`` is ``False``.
126140
ValueError: ``track`` contains a non-supported audio format.
127141
"""
128142
log.debug(f"Transcoding track. [{track=!r}, {to_format=!r}, {out_path=!r}]")
129143

144+
if out_path.exists() and not overwrite:
145+
raise FileExistsError(f"Given output path already exists. [{out_path=}]")
146+
130147
if not track.audio_format == "flac":
131148
raise ValueError(f"Track has unsupported audio format. [{track=!r}]")
132149

133150
out_path.parent.mkdir(parents=True, exist_ok=True)
134151
out_path = out_path.with_suffix(".mp3")
135152

136-
_transcode_path(track.path, to_format, out_path)
153+
_transcode_path(track.path, to_format, out_path, overwrite)
137154

138155
transcoded_track = Track.from_file(out_path)
139156
log.info(f"Transcoded track. [{transcoded_track=!r}]")
140157

141158
return transcoded_track
142159

143160

144-
def _transcode_path(path: Path, to_format: TranscodeFormat, out_path: Path) -> None:
161+
def _transcode_path(
162+
path: Path, to_format: TranscodeFormat, out_path: Path, overwrite: bool = False
163+
) -> None:
145164
"""Transcodes a file to `to_format`.
146165
147166
This is a separate function in order to support multiprocessing.
148167
"""
168+
if overwrite:
169+
overwrite_arg = "-y"
170+
else:
171+
overwrite_arg = "-n"
172+
149173
args = [
150174
"ffmpeg",
175+
overwrite_arg,
151176
"-loglevel",
152177
"error",
153178
"-i",

tests/test_transcode_core.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,28 @@ def test_quote_in_title(self):
7171

7272
assert transcoded_track.audio_format == "mp3"
7373

74+
def test_existing_file_dont_overwrite(self, tmp_path):
75+
"""If ``overwrite`` is False and the file exists, raise FileExistsError."""
76+
existing_mp3 = tmp_path / "exists.mp3"
77+
existing_mp3.touch()
78+
79+
track = track_factory(title="Jacob's Song", audio_format="flac", exists=True)
80+
81+
with pytest.raises(FileExistsError):
82+
transcode(track, "mp3 v0", out_path=existing_mp3)
83+
84+
def test_existing_file_overwrite(self, tmp_path):
85+
"""Overwrite existing files if ``overwrite`` is True."""
86+
existing_mp3 = tmp_path / "exists.mp3"
87+
existing_mp3.touch()
88+
track = track_factory(title="Jacob's Song", audio_format="flac", exists=True)
89+
90+
transcoded_track = transcode(
91+
track, "mp3 v0", out_path=existing_mp3, overwrite=True
92+
)
93+
94+
assert transcoded_track.audio_format == "mp3"
95+
7496

7597
@pytest.mark.usefixtures("_tmp_transcode_config")
7698
class TestTranscodeAlbum:

0 commit comments

Comments
 (0)