Skip to content

Add parser for reading from the song's tags or from a local .lrc/.lyric file#79

Open
alpemwarrior wants to merge 5 commits into
timoloewe:masterfrom
alpemwarrior:LocalFileLyrics
Open

Add parser for reading from the song's tags or from a local .lrc/.lyric file#79
alpemwarrior wants to merge 5 commits into
timoloewe:masterfrom
alpemwarrior:LocalFileLyrics

Conversation

@alpemwarrior
Copy link
Copy Markdown

The user can select "Local File" as a source, which will fetch lyrics from the song's metadata (mp3, ogg, opus and flac only) or from a .lrc or .lyric file with the same filename in the same path.
Also edited the README to mention the use of the mutagen library.

Copy link
Copy Markdown

@ratijas ratijas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice going! Just a few comments from me.

PS GitHub's ordering of comments is messed up, comparing to their top-to-bottom order, but you should get the idea.

Comment thread lLyrics/LocalParser.py Outdated
Comment on lines +113 to +120
try:
out = file["LYRICS"]
except:
pass
try:
out = file["UNSYNCEDLYRICS"]
except:
pass
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same.

You know, at this point, the whole file[...] retrieval deserves it's own function.

Comment thread lLyrics/LocalParser.py Outdated
Comment on lines +99 to +106
try:
out = file["LYRICS"]
except:
pass
try:
out = file["UNSYNCEDLYRICS"]
except:
pass
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same.

Comment thread lLyrics/LocalParser.py Outdated
Comment on lines +85 to +92
try:
out = file["LYRICS"]
except:
pass
try:
out = file["UNSYNCEDLYRICS"]
except:
pass
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is weird. In case both indexing operations succeed, second would just overwrite the variable. If they are mutually exclusive, could you explicitly mark them as such, please?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, you are right

Comment thread lLyrics/LocalParser.py Outdated
@@ -0,0 +1,123 @@
# -*- coding: utf-8 -*-
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder, is it still relevant in 2020, after Python-2's demise?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, it's useless. I just copied the template from another parser.

Comment thread lLyrics/lLyrics.py

LYRICS_SOURCES = ["Lyricwiki.org", "Letras.terra.com.br", "Metrolyrics.com", "AZLyrics.com", "Lyricsmania.com",
"Vagalume.com.br", "Genius.com", "Darklyrics.com", "Chartlyrics.com"]
"Vagalume.com.br", "Genius.com", "Darklyrics.com", "Chartlyrics.com", "Local File"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any i18n opportunity for plugins?

Comment thread lLyrics/LocalParser.py
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import urllib
import os.path as path
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW there's a modern pathlib out there, but otherwise it's not really much different.

Comment thread lLyrics/LocalParser.py Outdated
elif path.isfile(dir + self.title + ".lyric"):
return open(dir + self.title + ".lyric")
else:
return ""
Copy link
Copy Markdown

@ratijas ratijas Jul 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, this function returns either opened file object or a string. Sounds a little bit off. Better return None as usual, and check for it via is operator. Return type will be Optional[file] (well, kind of — since the open's real type would be _io._IOBase or its derivative).

@alpemwarrior
Copy link
Copy Markdown
Author

Thanks for the feedback! I'll rewrite it and update it. No idea about how the translation stuff works, but I'll look into it.
Also, there is an ugly patch in lLyrics.py because the parser needs the song url to work. Is this fine or is there a more elegant way to do it?

@alpemwarrior
Copy link
Copy Markdown
Author

I have looked into the translation stuff and it should be easy to do. Can't update any of them tho.
I decided not to use pathlib because the object syntax is just weird for what i'm trying to do, and os.path is not deprecated or anything. Other than that, everything else has been fixed.

Copy link
Copy Markdown

@ratijas ratijas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's definitely going somewhere the right way! Just few more nits, if you please.

Comment thread lLyrics/LocalParser.py Outdated
@@ -0,0 +1,105 @@
# Parses lyrics from a .lyric or .lrc file or from the tags of the song
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get it why this repository has no global LICENSE file, or why GPL text is fragmented via blank lines like that, but one thing is for sure: doc comments should be separate, inside triple double quotes and come after license text.

Also, lets call it "track" instead of "song". Even audio books and podcasts have 'lyrics' in them sometimes.

Suggested change
# Parses lyrics from a .lyric or .lrc file or from the tags of the song
"""
Parses lyrics from a .lyric or .lrc file or from the tags of the track.
"""

Comment thread lLyrics/LocalParser.py Outdated
def __init__(self, artist, title, song_path):
self.artist = artist
self.title = title
self.lyrics = ""
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused member self.lyrics.

Comment thread lLyrics/LocalParser.py Outdated
Comment on lines +58 to +59
# This only checks for .lrc or .lyric files with the same name as the song or with the same "cleaned" name as
# the song. If you have files in any other format, please add it to this function.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc comments

Suggested change
# This only checks for .lrc or .lyric files with the same name as the song or with the same "cleaned" name as
# the song. If you have files in any other format, please add it to this function.
"""
This only checks for .lrc or .lyric files with the same name as the song or with the same "cleaned" name as
the song. If you have files in any other format, please add it to this function.
"""

Comment thread lLyrics/LocalParser.py Outdated
elif path.endswith("flac"):
out = self.get_flac_lyrics(path)
if out is None:
file = self.check_for_file(dir, file_name)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name suggests it only checks, but in fact it opens a path and returns opened file. Since open calls are not guarded anyway, wouldn't it make more sense to return a string path here, and call open only once?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah returning open() is kinda sketchy anyway.

Comment thread lLyrics/LocalParser.py Outdated
out = ""
for line in file.readlines():
out += line
file.close()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to read line-by-line, and no need to manually close it with this syntax:

Suggested change
file.close()
with open(path) as file:
out = file.read()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

neat! Didn't know you could do that.

@alpemwarrior
Copy link
Copy Markdown
Author

Thanks again for your time and feedback!

@ratijas
Copy link
Copy Markdown

ratijas commented Aug 3, 2020

Hi, @dmo60. I think this is ready to squash & merge. Do you think you can take a look?

@ratijas
Copy link
Copy Markdown

ratijas commented Aug 19, 2020

@dmo60 Sorry to bump you on this, but it is kind of stagnating. Is there anything blocking from merge & release?

Alternatively, you could add me as a maintainer. I am skillful with Python and many other stuff, and I got a load of free time lately.

@wolf-yuan-6115
Copy link
Copy Markdown

@dmo60 Hello, any news for merging this into master?

@rexendevar
Copy link
Copy Markdown

dang i sure wish i had read the merge requests before duplicating all that effort lmao. and at the end of it all mine is worse and coded more poorly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants