#!/bin/bash # I, Ian Kelling, follow the GNU license recommendations at # https://www.gnu.org/licenses/license-recommendations.en.html. They # recommend that small programs, < 300 lines, be licensed under the # Apache License 2.0. This file contains or is part of one or more small # programs. If a small program grows beyond 300 lines, I plan to switch # its license to GPL. # Copyright 2024 Ian Kelling # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -e; . /usr/local/lib/bash-bear; set +e source /a/bin/ds/beet-data source /b/bash_unpublished/source-semi-priv declare -A genre_a for g in ${all_genres[@]}; do genre_a[$g]=t done # these options are mainly for debugging / developing quickly. plist_only=false dry_run=false while (( $# )); do case $1 in plist) plist_only=true shift ;; dry) dry_run=true shift ;; *) echo "error. unexpected arg read script" exit 1 ;; esac done m () { printf "%s\n" "$*" >&2 if $dry_run; then echo "dry run: $*" else "$@" fi } tmpf=$(mktemp) declare -A flacs declare -A navirating tmpdir=$(mktemp -d) cd $tmpdir # the code here is duplicated later for non ssh context. if [[ $HOSTNAME != kd ]]; then ssh b8.nz bash -s "$(md5sum $tmpf while read -r path; do beetrating[$path]=$r done <$tmpf done for path in "${!navirating[@]}"; do r="${navirating[$path]}" if [[ ! "${beetrating[$path]}" ]]; then if [[ -e $path ]]; then echo "$0: ERROR: $path exists but we have no rating for it" exit 1 else echo "$0: WARNING: $path exists in navidrome but not beets" continue fi fi if [[ $r != "${beetrating[$path]}" ]]; then echo "$r != ${beetrating[$path]}, beet modify -y path:$path rating=$r" beet modify -y "path:$path" "rating=$r" fi done # end star rating import from navidrome to beets: fi echo begin import navidrome playlists as flexible attribute with value t. shopt -s nullglob for path in 2genre/*/*; do id="${path#*/}" id="${id%/*}" filename="${path##*/}" tmp="${filename%%[^0-9-]*}" genre="${filename#"$tmp"}" if [[ ${genre_a[$genre]} ]]; then is_genre=true else # Some playlists we create with random names to remind us to do something # with these tracks later once we are at a computer. is_genre=false fi while read -r path; do flac="${path%.mp3}.flac" if [[ ${flacs[$flac]} ]]; then path="$flac" fi if $is_genre; then m beet modify -y "path:$path" "genre=$genre" else m beet modify -y "path:$path" "$genre=t" fi done <"$path" # how i figured this out: # s tcpdump -i any -w /tmp/tcpdump port 4533 # then delete a test playlist in client. # made some sense out of it with: http://www.subsonic.org/pages/api.jsp # open file in wireshard, right click "Hypertext Transfer Protocol", copy, as printable text, put into file /tmp/headers # /a/opt/h2c/h2c p while read -r path; do flac="${path%.mp3}.flac" if [[ ${flacs[$flac]} ]]; then path="$flac" fi m beet modify -y "path:$path" "$plist!" # files unique to tmpf are in beets not navidrome done < <(comm -23 p $plist) while read -r path; do flac="${path%.mp3}.flac" if [[ ${flacs[$flac]} ]]; then path="$flac" fi m beet modify -y "path:$path" $plist=t # files unique to plist are in navidrome not beets done < <(comm -13 p $plist) done cd rm -rf $tmpdir