google-code-export / beets

Automatically exported from code.google.com/p/beets
MIT License
0 stars 0 forks source link

Include lyrics plugin #137

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Having the ability to have let beets fetch track lyrics and embed them into the 
tags of the songs would be nice.

Original issue reported on code.google.com by pbrun...@gmail.com on 3 Feb 2011 at 5:52

GoogleCodeExporter commented 9 years ago
This would be a great simple plugin project if anyone's interested in 
contributing.

Original comment by adrian.sampson on 5 Feb 2011 at 12:12

GoogleCodeExporter commented 9 years ago
The folks at http://code.google.com/p/pylywi/ did a good job with lyrics 
fetching.
You can simply add this program to workflow, or someone can adapt the code to 
work with beets.
If I got some time I'll take a look

Original comment by andrea.g...@gmail.com on 9 Feb 2011 at 5:34

GoogleCodeExporter commented 9 years ago
Great pointer; thanks! It looks like they have a pretty straightforward 
interface available, too:
http://code.google.com/p/pylywi/source/browse/trunk/lytag/lytag.py#59

Original comment by adrian.sampson on 9 Feb 2011 at 5:46

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Well I decided to tinker w/ python, and attempt to update lytag to support 
everything that Beets does (by using Beet's wrapper for mutagen).
Then a little further research lead me to find out that you can't pull full 
lyrics from lyrics wiki anymore... so thats a dead end.

Original comment by pbrun...@gmail.com on 13 Feb 2011 at 10:16

GoogleCodeExporter commented 9 years ago
That's a shame! We'll have to find shadier ways of scraping a database for 
lyrics.

Original comment by adrian.sampson on 14 Feb 2011 at 2:22

GoogleCodeExporter commented 9 years ago
Managed to dig up some code to scrape the lyrics wiki for the proper data, and 
it seems to work. Trying to get a plugin working now... I wasn't able to get 
pluginpath to work though, is that broken? Also, any suggestions on where I 
should do the tagging in the plugin? I was thinking an event handler?   Sorry 
complete python noob here ;)

Original comment by pbrun...@gmail.com on 14 Feb 2011 at 2:30

GoogleCodeExporter commented 9 years ago
Pluginpath seems to be working for me... is there anything odd about your 
setup? One tricky detail is that all plugins need to be contained in a 
"beetsplug" namespace package (see the official distribution for an example of 
how to create such a package).

I good place to start might be with a command plugin. For example, we could add 
a command like this:
beet lyrics <query>
Which would fetch lyrics for all the matched songs. We could also add automatic 
lyrics-fetching for imported items using an event handler, but that has a 
performance cost and should probably be optional.

If you want to put your work so far on Github or BitBucket or wherever, I'd be 
glad to help out.

Original comment by adrian.sampson on 14 Feb 2011 at 3:21

GoogleCodeExporter commented 9 years ago
Yea I followed the guide on the wiki, but it refused to work. I finally ended 
up putting the same path that I had for pluginpath into the PYTHONPATH env-var 
and it worked fine...

Anyway, here is what I managed to put together so far:
https://github.com/Lugoues/beets-lyrics

Original comment by pbrun...@gmail.com on 14 Feb 2011 at 6:01

GoogleCodeExporter commented 9 years ago
Spent more time on this today. I found lrcShow-X which offers a nice library to 
fetch lyrics from multiple databases with. I have added that to my project and 
updated it.

If you could check it out I would be grateful :) Feel free to tell me if I'm 
doing something wrong.

Original comment by pbrun...@gmail.com on 15 Feb 2011 at 12:11

GoogleCodeExporter commented 9 years ago
Update #2 ;)
I attempted to thread the entire thing, to speed it up, with twisted. Its 
faster, but I have a feeling I'm doing something wrong with twisted. So far it 
is promising but issues remain, primarily some of the engines don't work...

Original comment by pbrun...@gmail.com on 15 Feb 2011 at 5:28

GoogleCodeExporter commented 9 years ago
Question: How do I get my plugin to load the engines module? I noticed that it 
only works when I'm in the plugin dir and use sys.path.append('./engines'). Is 
there a better way... I tried the __init__.py method but it doesn't work...

Original comment by pbrun...@gmail.com on 15 Feb 2011 at 8:13

GoogleCodeExporter commented 9 years ago
Cool! This is looking great. I sent you a pull request on Github that should 
(a) fix your pluginpath issues (just set pluginpath to the repository root -- 
the directory *containing* the beetsplug package) and (b) avoids using 
sys.path.append to import the engines package. (Absolute imports are your 
friend!) For not knowing much Python before starting this project, you've 
gotten pretty far! :)

If you don't mind, I might take a stab at doing concurrency without Twisted. 
While Twisted is nice for server stuff, it's sort of a heavy dependency for 
just using a worker pool. The standard library's multiprocessing module has a 
parallel map; I might also add similar functionality to the bluelet 
green-threading module I wrote for beets (https://github.com/sampsyo/bluelet) 
because network latency is the main thing that needs to be hidden here.

Original comment by adrian.sampson on 15 Feb 2011 at 11:33

GoogleCodeExporter commented 9 years ago
Got your changes and merged them thanks :)
Pluginpath still refuses to work though... my current config is below... Though 
now when i set my PYTHONPATH=~/dev/beets-lyrics it refuses to load the engine 
modules, I assume its all related though.

I thought twisted might be too heavy, it was suggested as the easiest way to 
get sync stuff going async, so I went with it. But do feel free to convert it, 
doing so is definitely on my list.

[beets]
directory: /mnt/raid/Music
library: ~/.beets/library.blb
import_copy: yes
import_art: yes
threaded: yes
color: yes
path_format: $artist/($year) $album/$track - $title
plugins: lyrics lastid
pluginpath: ~/dev/beets-lyrics

Original comment by pbrun...@gmail.com on 16 Feb 2011 at 12:27

GoogleCodeExporter commented 9 years ago
Update for today :)
I still haven't gotten pluginpath working, no clue why. I did fix the engine 
loading issue, by just creating the array of engines and passing it in instead 
of letting it try to find/load them itself.

I reworked the threading model. Dumped twisted and now I use multiprocess.pool 
instead.  It seems to be just as fast without all the overhead. Also fixed 
keyboard interrupt, cleaned the code up, and  the ability to set # of processes 
you wish to run

Original comment by pbrun...@gmail.com on 17 Feb 2011 at 4:33

GoogleCodeExporter commented 9 years ago
It's so strange that pluginpath isn't working for you. I don't have a good 
explanation -- have you tried using an absolute path instead of one with ~ in 
it? Not sure why that would help, but who knows.

The plugin is looking great. I'll take a closer look this weekend (I hope; I'll 
be traveling but I might have a bit of time). I'll need to start a "third party 
plugins" page here and I'll be sure to link to you. Eventually, maybe we should 
include it with the beets distribution.

Original comment by adrian.sampson on 17 Feb 2011 at 6:46

GoogleCodeExporter commented 9 years ago
Well I managed to get some more time to work on this and have made quiet a few 
updates. The plugin will now fetch lyrics on import, reworked the threading 
model (this new one is a better approach I think), and cleaned up some other 
things.

About the pluginpath issue: I originally had beets installed using pip, just 
the standard install your wiki suggests, and it was there that the pluginpath 
refused to work. After I uninstalled it and started running from the code 
pulled straight from github, everything worked fine... 

On another note, I attempted to use the event listener decorators that you have 
and being the python newbie that I am couldn't figure out how to get it to work 
while keeping the method inside of the class itself. So I ended up just setting 
the listeners member in the constructor. My question to you, is there a way to 
set the decorator while keeping the event method in the class? Or should I add 
a register_listener method in BeetsPlugin base class?

Original comment by pbrun...@gmail.com on 8 Apr 2011 at 3:27

GoogleCodeExporter commented 9 years ago
Awesome! The changes look great; I'll take another look at everything soon.

It's probably true that you can't use the decorator use the decorator inside 
the class declaration -- I'm not totally sure about Python's inheritance 
semantics, but I wouldn't be surprised if the decorator wasn't accessible 
inside the subclass declaration.

Really, I didn't intend a bunch of functionality to be thrown inside the plugin 
subclass. If you look at the plugins that ship with beets, most of the code is 
in module-global functions (no need for object-orientation here). Only the 
hooks into beets and the plugin system need be inside the class. But if you 
like to keep everything inside the class definition, that's of course OK. :)

Original comment by adrian.sampson on 8 Apr 2011 at 6:10

GoogleCodeExporter commented 9 years ago

Original comment by adrian.sampson on 17 Jan 2012 at 1:32

GoogleCodeExporter commented 9 years ago
A new, simplified lyrics plugin is included as of revision 6989f1a4370d. Docs:
http://readthedocs.org/docs/beets/en/latest/plugins/lyrics.html

Original comment by adrian.sampson on 19 Jan 2012 at 8:45