I'm trying to automate managing a converted library with hooks. When I update or remove an album in my main library (flac), I want to delete the converted version in ogg. For testing purposes, I am reimporting the same abum over and over to trigger the item_removed event.
This is my testing command, ran inside my flac directory so that beets reimports the album:
[cassie@forretress flac]$ beet -c ~/.config/beets/music.yaml -vv import "Tyler, the Creator - [2019] Igor (CD)/" -S https://musicbrainz.org/release/765263d3-4588-43ad-ba08-303b62b31e9e
This is one of the outputs of the hooks.
Sending event: item_removed
hook: running command "echo executing item_removed" for event item_removed
executing item_removed
hook: running command "dirname -- /mnt/raid/music/cassie/flac/Tyler, the Creator - [2019] Igor (CD)/01-01 Igor鈥檚 Theme.flac | echo" for event item_removed
/mnt/raid/music/cassie/flac/Tyler, the Creator - [2019] Igor (CD)
.
.
I can't figure out why there are two extra lines of .s. My initial attack was to simply call a script with an argument, but I can't figure out how to get the {item.path} to properly escape before being passed into the script.
Here is the relevant section of my configuration.
hook:
hooks:
- event: import
command: "beet -c /home/cassie/.config/beets/music.yaml convert -a -y -d /mnt/raid/music/cassie/ogg"
- event: item_removed
command: "echo executing item_removed"
- event: item_removed
command: "dirname -- {item.path} | echo"
Here is my entire configuration file: https://0x0.st/i-qm.txt
Reading the dirname manpage: Output each NAME with its last non-slash component and trailing slashes removed; if NAME contains no /'s, output '.' (meaning the current directory).
I think my problem lies in not knowing how to properly escape {item.path}, and nothing else.
Hi! This is admittedly pretty confusing, but interpolated values should be "magically" escaped automatically. Here's what the algorithm does:
dirname -- {item.path} | echo becomes 5 tokens.So what you're seeing is the output of dirname with three arguments: the path, the literal string |, and echo. Doing dirname on the latter two produces ..
So if you want to use proper shell constructs, you'll need to explicitly invoke sh. For example, something like this:
sh -c 'dirname $@ | echo' {item.path}
This is exactly what I needed. Thank you
Here's my eventual solution, for posterity.
music.yaml
hook:
hooks:
- event: import
command: "beet -c /home/cassie/.config/beets/music.yaml convert -a -y -d /mnt/raid/music/cassie/ogg"
- event: item_removed
command: "sh -c '/home/cassie/.config/beets/remove_item.sh $0' {item.path}"
remove_item.sh
#!/bin/bash
path="$@"
parent="$(dirname -- "$path")"
parent=$(printf '%s\n' "${parent}" | sed -e 's/flac/ogg/')
rm -vr "$parent" 2> /dev/null
exit 0
Awesome!!