diff --git a/supysonic/api/media.py b/supysonic/api/media.py index 27d7be1..33a49bd 100644 --- a/supysonic/api/media.py +++ b/supysonic/api/media.py @@ -316,6 +316,13 @@ def cover_art(): return send_file(cache.get(cache_key), mimetype=mimetype) +def lyrics_response_for_track(track, lyrics): + return request.formatter( + "lyrics", + dict(artist=track.album.artist.name, title=track.title, value=lyrics), + ) + + @api_routing("/getLyrics") def lyrics(): artist = request.values["artist"] @@ -323,6 +330,15 @@ def lyrics(): query = Track.select(lambda t: title in t.title and artist in t.artist.name) for track in query: + # Read from track metadata + lyrics = mediafile.MediaFile(track.path).lyrics + if lyrics is not None: + lyrics = lyrics.replace("\x00", "").strip() + if lyrics: + logger.debug("Found lyrics in file metadata: " + track.path) + return lyrics_response_for_track(track, lyrics) + + # Look for a text file with the same name of the track lyrics_path = os.path.splitext(track.path)[0] + ".txt" if os.path.exists(lyrics_path): logger.debug("Found lyrics file: " + lyrics_path) @@ -331,15 +347,12 @@ def lyrics(): with open(lyrics_path) as f: lyrics = f.read() except UnicodeError: - # Lyrics file couldn't be decoded. Rather than displaying an error, try with the potential next files or - # return no lyrics. Log it anyway. + # Lyrics file couldn't be decoded. Rather than displaying an error, try + # with the potential next files or return no lyrics. Log it anyway. logger.warning("Unsupported encoding for lyrics file " + lyrics_path) continue - return request.formatter( - "lyrics", - dict(artist=track.album.artist.name, title=track.title, value=lyrics), - ) + return lyrics_response_for_track(track, lyrics) # Create a stable, unique, filesystem-compatible identifier for the artist+title unique = hashlib.md5( diff --git a/tests/api/test_lyrics.py b/tests/api/test_lyrics.py index abbd0e3..c1cfea0 100644 --- a/tests/api/test_lyrics.py +++ b/tests/api/test_lyrics.py @@ -24,22 +24,33 @@ class LyricsTestCase(ApiTestBase): with db_session: folder = Folder( name="Root", - path=os.path.abspath("tests/assets"), + path=os.path.abspath("tests/assets/lyrics"), root=True, - cover_art="cover.jpg", ) - self.folderid = folder.id artist = Artist(name="Artist") album = Album(artist=artist, name="Album") Track( - title="23bytes", + title="Nope", number=1, disc=1, artist=artist, album=album, - path=os.path.abspath("tests/assets/23bytes"), + path=os.path.abspath("tests/assets/lyrics/empty.mp3"), + root_folder=folder, + folder=folder, + duration=2, + bitrate=320, + last_modification=0, + ) + Track( + title="Yay", + number=1, + disc=1, + artist=artist, + album=album, + path=os.path.abspath("tests/assets/lyrics/withlyrics.mp3"), root_folder=folder, folder=folder, duration=2, @@ -91,9 +102,15 @@ class LyricsTestCase(ApiTestBase): # Local file rv, child = self._make_request( - "getLyrics", {"artist": "artist", "title": "23bytes"}, tag="lyrics" + "getLyrics", {"artist": "artist", "title": "nope"}, tag="lyrics" ) - self.assertIn("null", child.text) + self.assertIn("text file", child.text) + + # Metadata + rv, child = self._make_request( + "getLyrics", {"artist": "artist", "title": "yay"}, tag="lyrics" + ) + self.assertIn("Some words", child.text) if __name__ == "__main__": diff --git a/tests/assets/23bytes.txt b/tests/assets/23bytes.txt deleted file mode 100644 index 2870fb5..0000000 --- a/tests/assets/23bytes.txt +++ /dev/null @@ -1 +0,0 @@ -That's a file full of null bytes diff --git a/tests/assets/empty b/tests/assets/empty deleted file mode 100644 index e69de29..0000000 diff --git a/tests/assets/lyrics/empty.mp3 b/tests/assets/lyrics/empty.mp3 new file mode 100644 index 0000000..5d0f06f Binary files /dev/null and b/tests/assets/lyrics/empty.mp3 differ diff --git a/tests/assets/lyrics/empty.txt b/tests/assets/lyrics/empty.txt new file mode 100644 index 0000000..177a1e0 --- /dev/null +++ b/tests/assets/lyrics/empty.txt @@ -0,0 +1 @@ +Lyrics in a text file next to a track without metadata. diff --git a/tests/assets/lyrics/withlyrics.mp3 b/tests/assets/lyrics/withlyrics.mp3 new file mode 100644 index 0000000..5e8ec96 Binary files /dev/null and b/tests/assets/lyrics/withlyrics.mp3 differ