beetbox / beets

music library manager and MusicBrainz tagger
http://beets.io/
MIT License
12.94k stars 1.82k forks source link

Scriptable Beets #1077

Open MacLeodMike opened 10 years ago

MacLeodMike commented 10 years ago

While it's true that beets can be extended with modules and plugins, sometimes it's hard to match the flexibility and ease offered by reasonably predictable output and a shell script. This was kicked off by this thread: https://groups.google.com/d/msg/beets-users/riHlzEDzPhE/kPo1GmrHtKMJ

I propose adding a new option to the beet command line (-s, --script, maybe?) that will modify beet's behaviour in three major ways:

There are a couple of behavioural considerations that I don't have an answer for: Single threaded but accepts multiple argument vs only working on a single input at a time - this might have an impact on how you want to handle stdout. Speaking of output, line buffered output vs buffering the import or the whole script run - need to consider how you'll keep the data in stdout paired with the command being run.

My particular use case involved running a beet import on each new release added to a directory. I only ever have one input argument and thus always know what my output will be concerning. So I don't have a strong opinion about how many arguments --script mode accepts or how the output is buffered. But anyone running bulk operations across large libraries might appreciate a considered solution.

sampsyo commented 10 years ago

Thanks for starting the conversation. I'm interested to see a fleshed-out design. Here are a few brief thoughts:

MacLeodMike commented 10 years ago

Your points are all valid. The choice of flag isn't really all that important, but I think you're probably correct that for now it's best to implement this on a command-by-command basis. I'd never seen beetwerk before - that's cool.

Option 1: beet import --simple is a truly lobotomized version of beets. It can only operate on one input path at a time. If you want beets to just work it's way through a directory of albums and import them and you're not doing further processing on a per-import level then just use the existing importer with --quiet.

Option 2: beet import --batch is basically the same as beet import --quiet, including the use of the multi-threaded importer, it just has more scriptable output. Don't worry about keeping output from multiple imports organized, just make each line relatively useful on it's own. "New_Album_Path=/path/to/foo", for example, and leave it to the user to make heads or tails of it - the assumption being that they're just grepping the output and operating on single lines of output. If the user wants the same behaviour as Option 1 then only ever call it with a single path. I assume imported albums (or singles or compilations) get some sort of ID in the DB, perhaps you could expose that in the logs: "9248.New_Album_Name=Foo Bar" followed by "9248.New_Album_Path=/path/to/bar". Line buffered tools wouldn't see any advantage, but perhaps someone doing something more complicated would.

Option 2 is probably the easiest, since you only have to modify the way beets handles output and it covers more use cases.

sampsyo commented 10 years ago

True; the simpler version could avoid making sweeping architectural changes. And it's a good observation that, even if the output can get garbled among multiple threads, the script doesn't have to pass more than one album at a time. :smiley: