beetbox / beets

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

Scriptable Beets #1077

Open MacLeodMike opened 9 years ago

MacLeodMike commented 9 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 9 years ago

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

MacLeodMike commented 9 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 9 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: