Skip to content

Commit

Permalink
save old and new state for every editing failure
Browse files Browse the repository at this point in the history
  • Loading branch information
girst committed Jan 4, 2021
1 parent f8c69f7 commit 313ac51
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 20 deletions.
44 changes: 26 additions & 18 deletions mopidy_spotify/playlists.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,24 +238,12 @@ def save(self, playlist):
# truncated the playlist. At this point, we still have the playlist
# data available, so we write it to an m3u file as a last resort
# effort for the user to recover from.
if ops_replace < ops_patch:
safe_name = playlist.name.translate(
str.maketrans(" @`!\"#$%&'()*+;[{<\\|]}>^~/?", "_" * 27)
)
filename = (
Extension.get_data_dir(self._backend._config)
/ f"{safe_name}-{playlist.uri}-{time.time()}.m3u"
)
with open(filename, "wb") as f:
f.write(b"#EXTM3U\n#EXTENC: UTF-8\n\n")
for track in playlist.tracks:
length = int(track.length / 1000)
artists = ", ".join(a.name for a in track.artists)
f.write(
f"#EXTINF:{length},{artists} - {track.name}\n"
f"{track.uri}\n\n".encode("utf-8")
)
logger.error(f'Created backup in "{filename}"')
# We'll save a backup of both the old and the new state,
# independent of which strategy was used, though, just to be safe.
filename = self.create_backup(saved_playlist, "old")
logger.error(f'Created backup of old state in "{filename}"')
filename = self.create_backup(playlist, "new")
logger.error(f'Created backup of new state in "{filename}"')
return None

if playlist.name and playlist.name != saved_playlist.name:
Expand All @@ -275,6 +263,26 @@ def save(self, playlist):

return self.lookup(saved_playlist.uri)

def create_backup(self, playlist, extra):
safe_name = playlist.name.translate(
str.maketrans(" @`!\"#$%&'()*+;[{<\\|]}>^~/?", "_" * 27)
)
filename = (
Extension.get_data_dir(self._backend._config)
/ f"{safe_name}-{playlist.uri}-{extra}-{time.time()}.m3u8"
)
with filename.open("w") as f:
f.write("#EXTM3U\n#EXTENC: UTF-8\n\n")
for track in playlist.tracks:
length = int(track.length / 1000)
artists = ", ".join(a.name for a in track.artists)
f.write(
f"#EXTINF:{length},{artists} - {track.name}\n"
f"{track.uri}\n\n"
)

return str(filename)


def playlist_lookup(
session, web_client, uri, bitrate, as_items=False, with_owner=False
Expand Down
18 changes: 16 additions & 2 deletions tests/test_playlists.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,12 +351,26 @@ def test_playlist_save_failed2(provider, mopidy_track_factory, caplog):
retval = provider.save(new_pl)
assert retval is None
assert "Failed to save Spotify playlist:" in caplog.text
assert "Created backup in" in caplog.text
assert "Created backup of old state in" in caplog.text
filename = next(
(
line.split('"')[1]
for line in caplog.text.split("\n")
if "Created backup in" in line
if "Created backup of old state in" in line
)
)
m3ucontents = open(filename).read()
assert (
m3ucontents
== "#EXTM3U\n#EXTENC: UTF-8\n\n#EXTINF:174,ABBA - ABC 123\nspotify:track:abc\n\n"
)

assert "Created backup of new state in" in caplog.text
filename = next(
(
line.split('"')[1]
for line in caplog.text.split("\n")
if "Created backup of new state in" in line
)
)
m3ucontents = open(filename).read()
Expand Down

0 comments on commit 313ac51

Please sign in to comment.