Merge pull request 'fix: remove playlists left behind by the switch to .m3u8' (#15) from fix/prune-superseded-playlists into main
Build and publish container / build (push) Successful in 2m41s
Build and publish container / build (push) Successful in 2m41s
Reviewed-on: #15
This commit was merged in pull request #15.
This commit is contained in:
+19
-1
@@ -75,6 +75,11 @@ PLAYLIST_DIRECTORY = "_playlists"
|
||||
# library holds Mötley Crüe, Beyoncé and Sigur Rós.
|
||||
PLAYLIST_SUFFIX = ".m3u8"
|
||||
|
||||
# Extensions this tool has written in the past. A playlist of the same name
|
||||
# under one of these is a leftover of its own, and is cleaned up even though no
|
||||
# record of writing it survives.
|
||||
SUPERSEDED_SUFFIXES = (".m3u",)
|
||||
|
||||
# Tags are re-fetched this often. They move slowly, and the first pass over a
|
||||
# library already costs one request per artist.
|
||||
TAG_REFRESH_SECONDS = 90 * 86400
|
||||
@@ -1674,9 +1679,22 @@ def prune_playlists(directory, produced, store):
|
||||
Driven by a record of what was written last time rather than by "every M3U
|
||||
that is not one of ours", so a playlist put there by hand is left alone. A
|
||||
renamed mood otherwise leaves its old file on the device for ever.
|
||||
|
||||
That record cannot reach back before it existed, which is how the switch
|
||||
from .m3u to .m3u8 left every playlist on the device twice: the old files
|
||||
were written by a version that kept no record, so there was nothing to
|
||||
prune them by. A file with the same name as one being written now, under a
|
||||
superseded extension, is therefore removed as well -- narrow enough that
|
||||
only this tool's own leavings match it.
|
||||
"""
|
||||
previous = set(json.loads(store.get_state("playlist_files") or "[]"))
|
||||
for name in sorted(previous - set(produced)):
|
||||
stale_names = previous - set(produced)
|
||||
for name in produced:
|
||||
for superseded in SUPERSEDED_SUFFIXES:
|
||||
stale_names.add(Path(name).with_suffix(superseded).name)
|
||||
stale_names -= set(produced)
|
||||
|
||||
for name in sorted(stale_names):
|
||||
stale = directory / name
|
||||
if stale.is_file():
|
||||
logger.info("removing playlist %s, no longer produced", name)
|
||||
|
||||
@@ -1504,3 +1504,35 @@ def test_the_old_m3u_playlists_are_pruned_after_the_rename(tmp_path):
|
||||
music_curator.prune_playlists(directory, ["screamo.m3u8"], store)
|
||||
|
||||
assert not (directory / "screamo.m3u").exists()
|
||||
|
||||
|
||||
def test_a_playlist_under_a_superseded_extension_is_removed(tmp_path):
|
||||
"""Switching from .m3u to .m3u8 left every playlist on the device twice.
|
||||
The old files predated the record of what had been written, so there was
|
||||
nothing to prune them by."""
|
||||
api, source, mirror = playlist_library(tmp_path)
|
||||
store = store_at(tmp_path)
|
||||
directory = mirror / "_playlists"
|
||||
directory.mkdir(parents=True, exist_ok=True)
|
||||
(directory / "screamo.m3u").write_text("#EXTM3U\n")
|
||||
(directory / "screamo.m3u8").write_text("#EXTM3U\n")
|
||||
|
||||
# No record at all, as on the first run after the rename.
|
||||
music_curator.prune_playlists(directory, ["screamo.m3u8"], store)
|
||||
|
||||
assert not (directory / "screamo.m3u").exists()
|
||||
assert (directory / "screamo.m3u8").is_file()
|
||||
|
||||
|
||||
def test_an_unrelated_m3u_is_still_left_alone(tmp_path):
|
||||
"""Only a name this run is writing anyway is matched, so a playlist made by
|
||||
hand survives whatever its extension."""
|
||||
api, source, mirror = playlist_library(tmp_path)
|
||||
store = store_at(tmp_path)
|
||||
directory = mirror / "_playlists"
|
||||
directory.mkdir(parents=True, exist_ok=True)
|
||||
(directory / "lyras-own-mix.m3u").write_text("#EXTM3U\n")
|
||||
|
||||
music_curator.prune_playlists(directory, ["screamo.m3u8"], store)
|
||||
|
||||
assert (directory / "lyras-own-mix.m3u").is_file()
|
||||
|
||||
Reference in New Issue
Block a user