Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Lyrics Grabber Feedback & Discussion (Read 256351 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Lyrics Grabber Feedback & Discussion

Reply #175
In foobar that's how we'd do the string simplification for common tag fields - easy (untested code, just to give an idea) :

Code: [Select]
$replace($lower($ascii(%album artist%)), ,,&,,",,'',,(,,-,,_,,),,=,,#,,{,,[,,\,,@,,],,°,,+,,},,$,,£,,%,,*,,',',,;,,:,,!,,?,,.,,/,,§,,)
$replace($lower($ascii(%album%)), ,,&,,",,'',,(,,-,,_,,),,=,,#,,{,,[,,\,,@,,],,°,,+,,},,$,,£,,%,,*,,',',,;,,:,,!,,?,,.,,/,,§,,)
$replace($lower($ascii(%title%)), ,,&,,",,'',,(,,-,,_,,),,=,,#,,{,,[,,\,,@,,],,°,,+,,},,$,,£,,%,,*,,',',,;,,:,,!,,?,,.,,/,,§,,)

Hope you get the idea. If we can do the same for the lyrics web sites data and compare the resulting strings, we'll have solved the problem, don't you think ?

BTW it would be nice if Lyrics Grabber could parse the %album artist% field BEFORE the %artist% field. I have the feeling that it only parses the %artist% field, which can lead to errors in many songs (e.g. all duets where %album artist% = name1 and %artist% = name1; name2)

Lyrics Grabber Feedback & Discussion

Reply #176
By now you could have made same python scripts  so why not try it? It's easy.
i.e. if you want to experiment improving some script by above suggestions, look for something like this in the script:

[font= "Lucida Console"]artist = handle.Format("[%artist%]")[/font]

and then change it to:

[font= "Lucida Console"]artist = handle.Format("[%artist%]").lower().replace('#','').replace('!','')[/font]...

only be careful with indentation

[edit] grammar

Lyrics Grabber Feedback & Discussion

Reply #177
Code: [Select]
def RemoveInvalidChars(field, replacing=['#','!' ETC]):
          field = handle.Format(field).lower()
          for n in replacing:
                  field = field.replace(n,'')
          return field

artist = Fields("[%artist%]")


Less code which is easier to maintain? It's probably some bugs or weird names in there, but the general idea...

EDIT: Forgot [code]s

Lyrics Grabber Feedback & Discussion

Reply #178
@2E7AH : unfortunately I have absolutely no experience with Python.  But if it's as easy as you say, then I'm sure somebody will come soon with a solution. Nemphael for example, if he feels up to the challenge.  I'm just giving some good ideas, that's all, but it will be up to T.P Wang or any Python scripter to translate them into usable things.

However, I still think these improvements should be made directly at the Lyrics Grabber level, not at the scripts level. Here's how I see it :

- If Lyrics Grabber itself was able to understand that the song "Apprends-moi" from album artist "Superbus" from album "Lova Lova" is THE SAME as the song "Apprends moi" from the same album artist and album,
- If Lyrics Grabber itself was able to understand that the song "Key Hole" from album artist "Superbus" from album "Lova Lova" is THE SAME as the song "Keyhole" from the same album artist and album,
- etc.

... then I believe that all scripts based on Lyrics Grabber should be able to benefit from this. Don't you think so ?

Those improvements should ideally be made at the "core", not script by script.

Lyrics Grabber Feedback & Discussion

Reply #179
Hmm... you are suggesting something like 3 custom input fields for artist-album-title somewhere in component's configuration. Not bad, but all scripts now will have to be changed (also the lyrics wiki and lyrics plugin).
Then also some (many I think) lyrics providers don't offer search with special chars, so you'll have to do the search for "Apprends-moi" and then again for "Apprends moi", or even worst case "Key Hole" and "Keyhole"

Lyrics Grabber Feedback & Discussion

Reply #180
Let's take the LyricWiki example, and type in a search for "Superbus Apprends-moi" (correct orthograph). Here are the results : http://lyricwiki.org/Special:GoogleSearchR...p;sa=Search#229

As you can see, the song "Apprends moi" is retrieved anyway, even if its title is different ! Why ? Because the integrated Google search "knows" that "Apprends moi" is "close" to "Apprends-moi", so the result can be relevant.

The same result could be obtained by googling the following query : 'Superbus "Apprends-moi" inurl:lyricwiki'. The result would of course be the same : http://www.google.fr/search?hl=fr&q=Su...mp;aq=f&oq=

So I think we could put this to use into Lyric Grabber. If Lyrics Grabber can use the integrated LyricWiki Google search, the search motor will hopefully do the rest. Don't you think so ?

Lyrics Grabber Feedback & Discussion

Reply #181
Here is simple python script for fetching time-stamped lyrics from the site I found today (lrcDB). It has 26252 records as now, not much, but they are time-stamped
@foorious I left input fields as is, so you can improve them

lrcDB.py
Code: [Select]
import encodings.utf_8
import urllib
from grabber import LyricProviderBase

class lrcDB(LyricProviderBase):
    def GetName(self):
        return "lrcDB"
   
    def GetVersion(self):
        return "0.1"
   
    def GetURL(self):
        return "http://www.lrcdb.org/search.php"
   
    def Query(self, handles, status, abort):
        result = []
        lid = ''

        for handle in handles:
            status.Advance()
           
            if abort.Aborting():
                return result
           
            artist = handle.Format("[%artist%]")
            album = handle.Format("[%album%]")
            title = handle.Format("[%title%]")

            try:
                string = urllib.urlopen("http://www.lrcdb.org/search.php?artist=%s&album=%s&title=%s&query=plugin&type=plugin" % (urllib.quote(artist), urllib.quote(album), urllib.quote(title))).read()
                lid = string.split(': ')[1]

                if lid > '' and len(lid) < 10:
                    lyric = urllib.urlopen("http://www.lrcdb.org/lyric.php?lid=%s&astext=yes" % lid).read()
                    result.append(lyric)

            except Exception, e:
                traceback.print_exc(file=sys.stdout)
                result.append('')
                continue
       
        return result

if __name__ == "__main__":
    LyricProviderInstance = lrcDB()

[!--sizeo:1--][span style=\"font-size:8pt;line-height:100%\"][!--/sizeo--][edit] last minute correction[/size]

Lyrics Grabber Feedback & Discussion

Reply #182
Some one can help and make script for http://www.plyrics.com please? thanks in advance

Lyrics Grabber Feedback & Discussion

Reply #183
The LrcDB.org main page says this :

Quote
Please don't use bots to search the site.
Posted by tonyc on 2008-08-08 18:50:05
I got an automated email today telling me the web server's CPU usage had spiked to 100%. It looks like someone was running a search bot through their entire MP3 collection and trying to download the lyrics for all of them from the site.

This type of activity brings the server to a crawl, so I have no choice but to block IP addresses that are doing this. This is the only way I can ensure the site is available for all of the other users.

One query per second is the maximum I will allow. Anyone sending queries faster than this on a regular basis will be blocked from the site.

Have things improved since then or not ? (it's been almost a year). I'm saying this because the site seemed to be under heavy load this morning...


Oh, and another thing : what about a Lyrics Grabber option (checkbox) that would allow timestamped lyrics to be downloaded, even if non-timestamped lyrics are already present in the %lyrics% tag ? (automatic replacement of non-timestamped lyrics by timestamped ones, optional of course).

Lyrics Grabber Feedback & Discussion

Reply #184
Some one can help and make script for http://www.plyrics.com please? thanks in advance
PLyrics is almost the same as AZ Lyrics, so changing the AZ Lyrics script a little will get you there. Anyway I made that another way using reg.exp and here it is:

pLyrics.py
Code: [Select]
import encodings.utf_8
import urllib
import re
from grabber import LyricProviderBase


class pLyrics(LyricProviderBase):
    def GetName(self):
        return "pLyrics (Punk)"

    def GetURL(self):
        return "http://www.plyrics.com"
   
    def GetVersion(self):
        return "0.1"

    def Query(self, handles, status, abort):
       
        rx_lrc = re.compile(r"(^(?!All lyrics)^\w.+|^\(.+)|^\w.+<br>",re.M)
        rx_str = re.compile(r"\W+")
        result = []
        lyric = []
       
        for handle in handles:
            status.Advance()
           
            if abort.Aborting():
                return result

            artist = handle.Format('[%artist%]')
            title = handle.Format('[%title%]')
           
            artist = rx_str.sub('',artist.lower())
            title = rx_str.sub('',title.lower())
   
            try:
                string = urllib.urlopen('http://www.plyrics.com/lyrics/'+artist+'/'+title+'.html').read()

                if string.find('Page Not Found') == -1:
                        for match in rx_lrc.finditer(string.replace('<br>','')):
                                lyric.append(match.group())
                else:
                        result.append('')
                        continue
               
                lyric = '\r\n'.join(lyric)
                result.append(lyric)

            except Exception, e:
                traceback.print_exc(file=sys.stdout)
                result.append('')
                continue
       
        return result

if __name__ == '__main__':
    LyricProviderInstance = pLyrics()

This is modified version for lrcDB script, which now looks for artist-title if artist-album-title fails:

lrcDB.py
Code: [Select]
import encodings.utf_8
import urllib
from grabber import LyricProviderBase

class lrcDB(LyricProviderBase):
    def GetName(self):
        return 'lrcDB (LRC)'

    def GetVersion(self):
        return '0.2'
   
    def GetURL(self):
        return 'http://www.lrcdb.org/search.php'

    def Query(self, handles, status, abort):
        result = []
        lid = ''

        for handle in handles:
            status.Advance()
           
            if abort.Aborting():
                return result

            artist = handle.Format('[%artist%]')
            album = handle.Format('[%album%]')
            title = handle.Format('[%title%]')

            try:
                string = urllib.urlopen('http://www.lrcdb.org/search.php?artist=%s&album=%s&title=%s&query=plugin&type=plugin' % (urllib.quote(artist), urllib.quote(album), urllib.quote(title))).read()

                if string == 'no match':
                    string = urllib.urlopen('http://www.lrcdb.org/search.php?artist=%s&title=%s&query=plugin&type=plugin' % (urllib.quote(artist), urllib.quote(title))).read()
                    if string == 'no match':
                        result.append('')
                        continue

                string = string.split('\t')[0]
                lid = string.split(': ')[1]

                if lid != '':
                    lyric = urllib.urlopen('http://www.lrcdb.org/lyric.php?lid=%s&astext=yes' % lid).read()
                    result.append(lyric)

            except Exception, e:
                traceback.print_exc(file=sys.stdout)
                result.append('')
                continue
       
        return result

if __name__ == '__main__':
    LyricProviderInstance = lrcDB()

Lyrics Grabber Feedback & Discussion

Reply #185
PLyrics is almost the same as AZ Lyrics, so changing the AZ Lyrics script a little will get you there.
i try, but no results
many thanks for script!

hmm, its work only for single track :/ if i choose full album only first track success

http://plyrics.com/a/alexisonfire.html

Lyrics Grabber Feedback & Discussion

Reply #186
I tested it only on one track  , try this:

Code: [Select]
import encodings.utf_8
import urllib
import re
from grabber import LyricProviderBase


class pLyrics(LyricProviderBase):
    def GetName(self):
        return "pLyrics (Punk)"

    def GetURL(self):
        return "http://www.plyrics.com"
   
    def GetVersion(self):
        return "0.1"

    def Query(self, handles, status, abort):
       
        rx_lrc = re.compile(r"(^(?!All lyrics)^\w.+|^\(.+)|^\w.+<br>",re.M)
        rx_str = re.compile(r"\W+")
        result = []
        lrc = []
       
        for handle in handles:
            status.Advance()
           
            if abort.Aborting():
                return result

            artist = handle.Format('[%artist%]')
            title = handle.Format('[%title%]')
           
            artist = rx_str.sub('',artist.lower())
            title = rx_str.sub('',title.lower())
   
            try:
                string = urllib.urlopen('http://www.plyrics.com/lyrics/'+artist+'/'+title+'.html').read()

                if string.find('Page Not Found') == -1:
                        for match in rx_lrc.finditer(string.replace('<br>','')):
                                lrc.append(match.group())
                else:
                        result.append('')
                        continue
               
                lyric = '\r\n'.join(lrc)
                result.append(lyric)

            except Exception, e:
                traceback.print_exc(file=sys.stdout)
                result.append('')
                continue
       
        return result

if __name__ == '__main__':
    LyricProviderInstance = pLyrics()

Lyrics Grabber Feedback & Discussion

Reply #187
Here is another script, with the same reg.ex method for Lyrics.net.ua (184912 records as now)

lyricsNET.py
Code: [Select]
import encodings.utf_8
import urllib
import re
from grabber import LyricProviderBase

class LyricsNET(LyricProviderBase):
    def GetName(self):
        return "Lyrics.NET"

    def GetURL(self):
        return "http://lyrics.net.ua"

    def GetVersion(self):
        return "0.1"

    def Query(self, handles, status, abort):

        rx_lrc = re.compile(r"^\w.*<br />$|<p class=text>\w.*<br />",re.M)
        rx_str = re.compile(r"(?!\w+?)\W+?")
        rx_htm = re.compile(r"<.*?>")
        result = []
        lrc = []

        for handle in handles:
            status.Advance()

            if abort.Aborting():
                return result

            artist = handle.Format('[%artist%]')
            album = handle.Format('[%album%]')
            title = handle.Format('[%title%]')

            artist = rx_str.sub('_',artist.lower().replace('&','_amp_'))
            album = rx_str.sub('_',album.lower().replace('&','_amp_'))
            title = rx_str.sub('_',title.lower().replace('&','_amp_'))

            try:
                string = urllib.urlopen('http://lyrics.net.ua/lyrics/'+artist+'/'+album+'/'+title+'.html').read()

                if string.find('failed to open stream') == -1:
                        for match in rx_lrc.finditer(string):
                                lrc.append(rx_htm.sub('',match.group()))
                else:
                        result.append('')
                        continue

                lyric = '\r\n'.join(lrc)
                result.append(lyric)

            except Exception, e:
                traceback.print_exc(file=sys.stdout)
                result.append('')
                continue

        return result

if __name__ == '__main__':
    LyricProviderInstance = LyricsNET()


Lyrics Grabber Feedback & Discussion

Reply #189
IMO we're all talking much about the scripts and not enough about Lyrics Grabber.

Maybe there should be a separate topic for all Lyrics Grabber scripts, so that we can keep discussing about Lyrics Grabber development and improvements.

Lyrics Grabber Feedback & Discussion

Reply #190
I've made couple of new scripts which I posted here
Don't want to trash this thread and also to avoid possible indentation error when user manages script

@T.P.Wang: I was trying to convert HTML enteties to unicode with "htmlentitydefs" and then with "BeautifulSoup", but always get this same message:
Code: [Select]
foo_grabber_python: TypeError: No registered converter was able to produce a C++ rvalue of type class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > from this Python object of type NavigableString

[edit] If someone knows of LRC (time-stamped) lyrics site or service, please post

Lyrics Grabber Feedback & Discussion

Reply #191
I got an error:

Code: [Select]
foo_grabber_python: Traceback (most recent call last):
  File "C:\Program Files\foobar2000\pygrabber\scripts\LyricsTXT.py", line 35, in Query
    url = 'http://www.lyricstxt.com/lyrics/'+artist[0]+'/'+artist+'/'+title+'_lyrics.html'
IndexError: string index out of range


Is it the script or the plugin?

Lyrics Grabber Feedback & Discussion

Reply #192
Is that error for some particular artist/album?

There is (mistype) error in the script at line 42:

[font= "Lucida Console"]if link == None:[/font]

should be:

[font= "Lucida Console"]if lyric == None:[/font]

Also read request will stop at " ’ " - char(8217) - that is fixed and can be downloaded from here

If you notice any other anomaly, please report.

Lyrics Grabber Feedback & Discussion

Reply #193
Python script for fetching AMG review (album) here

Allmusic has some limitation on number of accesses per IP. I don't know the number but it shouldn't worry us too much because in this case access is per album not per track. Of course use it with common sense.
For any error please post.

Lyrics Grabber Feedback & Discussion

Reply #194
Is there some way to use python debugger? I mean where is module grabber? Is it wrapped in foo_grabber_python.dll?

Lyrics Grabber Feedback & Discussion

Reply #195
T.P.Wang: I was trying to convert HTML enteties to unicode with "htmlentitydefs" and then with "BeautifulSoup", but always get this same message:
Code: [Select]
foo_grabber_python: TypeError: No registered converter was able to produce a C++ rvalue of type class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > from this Python object of type NavigableString

Sorry for my late reply.
You should use str(instance of NavigableString, 'utf_8') in order to convert it to utf-8 first.

Is there some way to use python debugger? I mean where is module grabber? Is it wrapped in foo_grabber_python.dll?

Yes, module grabber is embedded into foo_grabber_python.dll. It's always a headache to debug scripts.
I'd suggest write common scripts in a python IDE which contains debugging, then migrate them in foo_grabber_python env.


PS: I don't forget this project, there's a lot of inner changes in my current developing version (not compatable with previous versions), and changed frequently, and I'll consider a better configuration dialog (I mean I'm not good at designing a GUI, It always takes me a lot of time...  )

Lyrics Grabber Feedback & Discussion

Reply #196
You should use str(instance of NavigableString, 'utf_8') in order to convert it to utf-8 first.

I don't remember what I was doing back then, because I left the code. Trying now they both work fine
I guess passed string(?) was not in utf-8

I'd suggest write common scripts in a python IDE which contains debugging, then migrate them in foo_grabber_python env.

OK 
I got this very nice PyScripter and feel uncomfortable tracing strange behaviours with SciTE and foobar console

And looking forward to next python_grabber release  (especially "custom meta field-value pair")

Lyrics Grabber Feedback & Discussion

Reply #197
@T.P.Wang: I was testing Gracenote grabber script, and thought to suggest something regarding multiple tag value pairs:
- possibility to call simple dialog within the script so user can select which tags to be written and option for custom tag mapping

For example, AMG script can fetch at least: AMG REVIEW, GENRE, STYLE, MOOD, THEME, PUBLISHER, DATE, COMPOSER, RELEASES... from url respond.
So if I call this suggested dialog function from script, it will pop dialog box at user request with all defined tags contained in the script and some tick box for selecting/deselecting which tags to be written (and maybe input box aside tags for custom tag mapping defaulting to tag defined in script)

Lyrics Grabber Feedback & Discussion

Reply #198
...or that can be appended on existing querying result dialog, which is probably better, but with losing option for choosing tag before script search starts

Lyrics Grabber Feedback & Discussion

Reply #199
hi i have been using foo_uie_lyrics, but sometimes its online search does not find the song i am playing. i like how foo_uie_lyrics does not change the tag.

is there anyway to make lyrics grabber download the  lyrics instead of putting it into the tag like how foo_uie_lyrics lets you save to config folder?

thanks!