Skip to content

Instantly share code, notes, and snippets.

@jordandrako
Last active July 6, 2025 14:33
Show Gist options
  • Save jordandrako/e7082a6ad3d90b85df36017bb97a02f3 to your computer and use it in GitHub Desktop.
Save jordandrako/e7082a6ad3d90b85df36017bb97a02f3 to your computer and use it in GitHub Desktop.
[Un]monitor Albums in Lidarr
#!/bin/bash
helpText="
# Usage:\n
#\n
# ./monitor_albums.sh -k 'apiKey' -b 'http://host:port' -t [Single|EP|Album] [-m|u|A|h][-n 'artist name'][-i artistId]\n
#\n
# Required Options:\n
# -k Your Lidarr API Key (defaults to \$apiKey env variable)\n
# -b Your Lidarr instance URL (defaults to \$baseUrl env variable)\n
# -t The album type you want to monitor/unmonitor (album, ep, single, etc)\n
# -m|u [Un]Monitor the found albums\n
#\n
# Artist Options:\n
# -A Unmonitors all <albumType> from all artists\n
# -n 'artist name' Unmonitors all <albumType> from specified artist by name\n
# -i artistId Unmonitors all <albumType> from specified artist by ID\n
# -h Help text\n
"
ask() {
if [[ ! $1 ]]; then
error "You must pass a question to ask!"
else
question=$1
input=${2:="y/n"}
echo -e "\n\e[1;34m$question\e[0m" && echo "[$input] > "
[[ $3 ]] && read $3
fi
}
[[ ! $* ]] && echo -e $helpText && exit 1
while getopts k:b:t:i:n:Ahum flag; do
case ${flag} in
k)
apiKeyArg=${OPTARG};;
b)
baseUrlArg=${OPTARG};;
u)
monitored=false;;
m)
monitored=true;;
t)
albumType=${OPTARG};;
i)
artistId=${OPTARG};;
n)
artistName=${OPTARG};;
A)
all=true;;
h)
echo -e $helpText;
exit 0;;
\?)
echo "Invalid option: -$OPTARG" >&2;
exit 1;;
:)
echo "Option -$OPTARG requires an argument." >&2;
exit 1;;
esac
done
apiKey="${apiKeyArg:=$apiKey}"
baseUrl="${baseUrlArg:=$baseUrl}/api/v1"
[[ ! $apiKey ]] && echo "No api key specified. Use -k or 'export apiKey=yourkeyhere'." && exit 1
[[ $baseUrl == "/api/v1" ]] && echo "Lidarr URL not specified. Use -b or 'export baseUrl=http://host:port'." && exit 1
[[ ! $monitored ]] && echo "Must specify -m monitor or -u to unmonitor!" && exit 1
[[ ! $albumType ]] && echo "Must specify -t albumType!" && exit 1
if [[ $artistName != "" ]]; then
echo "Looking for artist $artistName"
artists=`curl "$baseUrl/artist?apiKey=$apiKey" -s`
artistId=`echo $artists | jq --arg artistName "$artistName" '
.[]
| select(.artistName == $artistName)
| .id'`
if [[ $artistId != "" ]]; then
echo "Artist found."
else
echo "Artist not found."
exit 1
fi
elif [[ $artistId != "" ]]; then
echo "Looking artist by id $artistId"
artist=`curl "$baseUrl/artist/$artistId?apiKey=$apiKey" -s`
artistName=`echo $artist | jq .artistName`
if [[ $artistName != null ]]; then
echo "Artist found: $artistName"
else
echo "Artist not found."
exit 1
fi
fi
[[ $all != true ]] && query="&artistId=$artistId" || query=""
[[ $all == true ]] && echo "Fetching all artists..."
albums=`curl "$baseUrl/album?apiKey=$apiKey$query" -s`
foundAlbums=`echo $albums | jq --arg albumType "$albumType" '[.[] | select(.albumType | test($albumType, "i")) | { title: .title, id: .id}]'`
albumNames=`echo $foundAlbums | jq '.[] | .title'`
albumIds=`echo $foundAlbums | jq '[.[] | .id]'`
[[ $monitored == true ]] && monitorString=monitor || monitorString=unmonitor
ask_artist() {
while true; do
ask "Are you sure you want to $monitorString the following $albumType(s) from \"$artistName\"?:\n$albumNames" "N/y" conYn
case $conYn in
[yY]* )
cont;
break;;
* )
echo "Cancelled";
exit 0;;
esac
done
}
ask_all() {
while true; do
ask "Are you sure you want to $monitorString $albumType(s) from all artists?:\n$albumNames" "N/y" conYn
case $conYn in
[yY]* )
cont;
break;;
* )
echo "Cancelled";
exit 0;;
esac
done
}
generate_put_data() {
cat <<EOF
{
"albumIds": $albumIds,
"monitored": $monitored
}
EOF
}
cont() {
curl -X PUT -H "Content-Type: application/json" -d "$(generate_put_data)" "$baseUrl/album/monitor?apiKey=$apiKey" --silent > /dev/null
}
# No found albums
[[ ${#foundAlbums} -lt 3 ]] && echo "No $albumType(s) found for $artistName" && exit 1
# Confirm operation
[[ $all == true ]] && ask_all || ask_artist
@VeteraNovis
Copy link

@jordandrako It looks like there's a small bug in your case insensitive filter

select(.albumType | test($albumType, "i"))

You need to use a semi-colon between the STRING / FLAG

select(.albumType | test($albumType; "i"))

It's also useful to convert a standard - to the U+2010 dash used by musicbrainz

artistName=$(echo $artistName | sed 's/-/‐/g')

Regardless, thanks for the script, really useful!

@bonelifer
Copy link

@VeteraNovis do we add artistName=$(echo $artistName | sed 's/-/‐/g') after:
albumIds=echo $foundAlbums | jq '[.[] | .id]'

@notmayo
Copy link

notmayo commented Jan 20, 2025

Awesome work! This works beautifully in 2025 with the latest Lidarr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment