1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-22 17:06:17 +00:00

Read lyrics from metadata

Closes #212
This commit is contained in:
Alban Féron 2021-01-23 17:16:15 +01:00
parent 05b1a1123f
commit bd370f57ff
No known key found for this signature in database
GPG Key ID: 8CE0313646D16165
7 changed files with 44 additions and 14 deletions

View File

@ -316,6 +316,13 @@ def cover_art():
return send_file(cache.get(cache_key), mimetype=mimetype) 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") @api_routing("/getLyrics")
def lyrics(): def lyrics():
artist = request.values["artist"] 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) query = Track.select(lambda t: title in t.title and artist in t.artist.name)
for track in query: 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" lyrics_path = os.path.splitext(track.path)[0] + ".txt"
if os.path.exists(lyrics_path): if os.path.exists(lyrics_path):
logger.debug("Found lyrics file: " + lyrics_path) logger.debug("Found lyrics file: " + lyrics_path)
@ -331,15 +347,12 @@ def lyrics():
with open(lyrics_path) as f: with open(lyrics_path) as f:
lyrics = f.read() lyrics = f.read()
except UnicodeError: except UnicodeError:
# Lyrics file couldn't be decoded. Rather than displaying an error, try with the potential next files or # Lyrics file couldn't be decoded. Rather than displaying an error, try
# return no lyrics. Log it anyway. # with the potential next files or return no lyrics. Log it anyway.
logger.warning("Unsupported encoding for lyrics file " + lyrics_path) logger.warning("Unsupported encoding for lyrics file " + lyrics_path)
continue continue
return request.formatter( return lyrics_response_for_track(track, lyrics)
"lyrics",
dict(artist=track.album.artist.name, title=track.title, value=lyrics),
)
# Create a stable, unique, filesystem-compatible identifier for the artist+title # Create a stable, unique, filesystem-compatible identifier for the artist+title
unique = hashlib.md5( unique = hashlib.md5(

View File

@ -24,22 +24,33 @@ class LyricsTestCase(ApiTestBase):
with db_session: with db_session:
folder = Folder( folder = Folder(
name="Root", name="Root",
path=os.path.abspath("tests/assets"), path=os.path.abspath("tests/assets/lyrics"),
root=True, root=True,
cover_art="cover.jpg",
) )
self.folderid = folder.id
artist = Artist(name="Artist") artist = Artist(name="Artist")
album = Album(artist=artist, name="Album") album = Album(artist=artist, name="Album")
Track( Track(
title="23bytes", title="Nope",
number=1, number=1,
disc=1, disc=1,
artist=artist, artist=artist,
album=album, 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, root_folder=folder,
folder=folder, folder=folder,
duration=2, duration=2,
@ -91,9 +102,15 @@ class LyricsTestCase(ApiTestBase):
# Local file # Local file
rv, child = self._make_request( 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__": if __name__ == "__main__":

View File

@ -1 +0,0 @@
That's a file full of null bytes

View File

Binary file not shown.

View File

@ -0,0 +1 @@
Lyrics in a text file next to a track without metadata.

Binary file not shown.