Beets: path queries. disable sorting output

Created on 17 Oct 2019  路  4Comments  路  Source: beetbox/beets

Use case

Hi, I am working on a little script that uses Rofi as a pseudo gui for playing, controlling, etc beets queries. Part of the functionality is displaying a track queue.

rofi-2019-10-16-1730-00000

I often make randomly sorted playlists that are generated from querying a specific genre, or user defined attributes like, Loved, Focus, Workout, Chill, etc. and returning a random subset of the results. Currently, to format a playlist/queue for viewing in Rofi I am just processing the standard m3u playlist (file paths) generated by my script and redirecting the formatted output to a separate tmp file. Here is the messy function...

function listQ() {
    tmpLIST=( /tmp/*.m3u )
    < ${tmpLIST} sed 's/.*/path:"&", /; $s/, $//' \
      | xargs beet ls -f "\$albumartist$S\$album$S\$title$S\$genre$S\$year$S\$format$S\$id" \
      | sed -r '/^\s*$/d' \
    > /tmp/tmp.beetq
}

The m3u file is processed so that each new line is an or query...

path:"/mnt/Data/Music/Scores/J贸hann J贸hannsson/2016 - Arrival/09 - Ultimatum.flac", 
path:"/mnt/Data/Music/Composers/袙械谢懈泻懈械 泻芯屑锌芯蟹懈褌芯褉褘. 袞懈蟹薪褜 懈 褌胁芯褉褔械褋褌胁芯/42 - 袦芯褑邪褉褌/11. Mozart - Requiem - V Sanctus.mp3", 
path:"/mnt/Data/Music/Composers/Frederic Chopin; Alice Sara Ott/2010 - Chopin_ Complete Waltzes/12 - Waltz in F minor, Op. posth. 70 No. 2.flac"

QUESTION:

When querying paths with beet ls ... is it possible to not sort the output? More specifically, make the output retain the order the queries were made.

I could iterate over the playlist and query each line individually...

< ${tmpLIST} \
    | parallel -q beet ls -f "\$albumartist$S\$album$S\$title$S\$genre$S\$year$S\$format$S\$id" \
    | sed -r '/^\s*$/d' \
> /tmp/tmp.beetq

But that approach is painfully slow.

Any thoughts or ideas would be greatly appreciated. I have been using beets for about a year but I am just now really trying to learn the ins and outs.

Thanks for your time and sharing this amazing tool!

needinfo stale

All 4 comments

Wow; this is a pretty neat setup! Thanks for the detailed explanation and the examples.

While I see the goal, the answer is no, this isn't currently possible. And what's worse, I don't see an easy way to add it. Your beets query there is being translated into a SQL query that essentially says SELECT * FROM items WHERE path=% OR path=% OR .... That means that things, if they were unsorted, would be returned in "database order," not in "query order."

I wonder if the right thing might not be to create a plugin that doesn't take a normal query鈥攊nstead, it just takes a list of paths directly. Then, the plugin could look up each path quickly and print out the information. It would be like beet list but _just for paths_. It wouldn't be a hard plugin to write, I think, but it would be distinct from the "real" list command.

I appreciate the very informative explanation, Thank you!

I do not know SQL, but I am using this project as a way to get familiar with it, or sqlite specifically. So for learning sake and a couple other reasons I am using a separate database for use with my script(s). I'm basically just dumping the fields I need from beets and importing them into my very basic db.

... That means that things, if they were unsorted, would be returned in "database order," not in "query order."

That would explain it :)

The function in my first comment is the only instance that I query beets.db directly. For a little exercise to help myself understand, I put together a similar query to my rofi_beets.db, which in hindsight I am unsure why I did not at least try doing so earlier....

function listQ() {
    S="^"
    tmpLIST=( /tmp/*.m3u )
    # format 'tmplist' for sqlite query
    playlist=$(<$tmpLIST awk '{ printf "%s\"%s\"", sep, $0; sep=",\n" } END { print "" }') 
    sqlite3 ${rofi_beetsDB} "SELECT albumartist || '$S' || album || '$S' || title || '$S' || genre || '$S' || year || '$S' || format || '$S' || id \
                FROM Beets WHERE path IN (${playlist});" \
    > /tmp/tmp.beetq
}

And indeed, without defining an ORDER the items are returned in "database order", as you stated they would be. While reading up some more on sqlite I found a thread ORDER BY the IN value list that has the same end goal as mine, but I believe the solutions are specific to PostgreSQL.

...the plugin could look up each path quickly and print out the information. It would be like beet list but just for paths

Interesting thought! I am not much of a programmer, more a hobbyist trying to learn in any downtime I can get. This project of mine is about half shell script and half lua, latter being what I am most familiar with. But with Beets great documentation and some patience I may be able to fake it to a working python plugin. Hmmm...

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Closing as no longer relevant.

Was this page helpful?
0 / 5 - 0 ratings