Putting a comment in Path

As some background, I’m collecting music and placing it in a subfolder based on it’s copyright/copyleft information. For ease of use I’ve put a new tag in each MP3 named “copyfolder” and the tag can hold information like “CC-BY” “CC-BY-NC” and so on. It’s fairly straightforward, but I’m having the damndest time navigating the docs, to figure out which feature I should be using to make this work. Beets is currently throwing me an exception saying the inline path field “copyfolder” isn’t defined. These are the relevant bits I have in my config so far. I feel I may be out of my depth here.

paths:
default: $copyfolder/$albumartist - $album%aunique{}/$track - $title
singleton: $copyfolder/Non-Album/$artist - $title
comp: $copyfolder/Compilations/$album%aunique{}/$track - $title

item_fields:
copyfolder: u"%s" % (copyfolder)

Hi! The “beets way” to do this would be to use beet modify to set this field on the relevant albums. There’s not exactly an easy way to get this data from actual ID3 tags, but it is possible with a custom plugin (searching on this forum for “custom tag mapping” might help).

Thanks for the reply. Setting the tag isn’t the issue I’m having. Getting an already set tag back out to sort music in the filesystem is where I’m stuck.

That’s the thing: even if you’ve set the tag with another tool, beets doesn’t know it. But using the modify command, you can set a “flexible attribute” (another search term you can try!) that beets does know about and that you can use in path templates.

OOOooooh. I’m curious if that’s what was getting me tripped up. I’ve seen flexible attributes, the inline plugin, and what not. Feel like those could get me where I’m headed. I was thinking beets read files then applies it’s tricks, but you seem to be saying it reads the files, puts it in the database, then uses the database to do it’s tricks.

Yep, exactly!

So just to be sure, It’ll be a /few/ step process to get files in the place I want them to be. First import the files that have the tag. Second search for tag “copyfolder” and set a “flexible attribute” with the search results, then re-run the app to apply “copyfolder” attribute contents to the path. I won’t be able to do it in just one step?

Seems like I’m getting this wrong cause I thought the whole point of the app was to get rid of fiddling with files and tags manually.

It looks like this user was trying to do something similar. How to use Custom Fields?

So I think I’ll be needing to write a plugin to accomplish.

Alright! Just figured it out after staring at it for too long! SO for anyone trying to get this bad magic done in the future. Here’s what I ended up with

My config is the stock config with these tweaks.

paths: $FlexibleField/$albumartist/$track $title

item_fields:
    FlexibleField: FlexibleField

/Then/, when you’re running an import job you can set “FlexibleField” for the beet database with this little gem of a command:

beet import --set=FlexibleField=foo /your/music/here/ 

And wiz-bang it’ll put the files in foo folder like one would want. Thanks for the help @adrian, I was about ready to just use Picard the “hard” way!

Excellent! Indeed, you got it!

Well, I still need to figure out how to import it from an Idv3tag, or even base the folder it goes in from the copyright comment left in the file tag… but at least it’s doing what I’d like for the time being. Though to be honest I’m having a hard time mustering up the will to figure out how to write a plugin when I’ll need to check every file anyway. This software, thought super powerful, may just not fit my use case. It seems like it may add /more/ work to my sorting at any rate.

@fullstopslash You could use mid3v2 to extract your custom tag per file, and pass it along to each import command’s --set:

find /your/music/here/ -name '*.mp3' | while read f
do
tag=$(mid3v2 -l "$f" | grep TBPM)
copyfolder=${tag#*=}
beet import -s --set copyfolder="$copyfolder" "$f"
done

Which, together with appropriate inline plugin path rules will file each singleton into the desired place.

Three caveats come to mind:

  1. Will trigger a separate import command per file, which will be slower.
  2. Will not work with albums as written above. You’d have to tune the script to somehow detect/loop over each album folder separately, scanning the first audio file inside that folder for its copyfolder tag (assuming that for albums, every audio file has the same copyfolder?).
  3. The beets import command is interactive, and doesn’t work well in a while loop when prompting you to make decisions. You’d need to either: A) echo the beet import commands to a file that you can then check and execute as a script after you decide you like it; or B) pass -q to beet import to use it non-interactively (but then you might want to crank up the strong_rec_thresh under match: in your config.yaml to avoid beets skipping a bunch of files).

I’d recommend doing (3) regardless, so that you can validate by eye what you are planning to feed to beets. And then you can combine elements of (2) into your to-be-executed script as well, while at it.