#!/bin/bash export LC_ALL=C.UTF-8 # usage: import_music.sh [--move] [--timid|--skip-beets] IMPORT_DIR="/mnt/media/slskd/downloads" LIBRARY_DIR="/mnt/media/MusicTest" # Parse flags MOVE_FILES=false BEETS_FLAG="" for arg in "$@"; do case $arg in --move) MOVE_FILES=true ;; --timid|--skip-beets) BEETS_FLAG="$arg" ;; *) echo "Unknown option: $arg" echo "Usage: $0 [--move] [--timid|--skip-beets]" exit 1 ;; esac done # Build original metadata map declare -A ORIGINAL_ARTIST_MAP declare -A ORIGINAL_ALBUM_MAP while IFS= read -r file; do orig_artist=$(metaflac --show-tag=ALBUMARTIST "$file" | sed 's/^ALBUMARTIST=//') orig_album=$(metaflac --show-tag=ALBUM "$file" | sed 's/^ALBUM=//') ORIGINAL_ARTIST_MAP["$file"]="$orig_artist" ORIGINAL_ALBUM_MAP["$file"]="$orig_album" done < <(find "$IMPORT_DIR" -type f -name "*.flac") # Optional beets import case "$BEETS_FLAG" in --timid) echo "Running beet import --timid..." beet import "$IMPORT_DIR" --timid ;; --skip-beets) echo "Skipping beets import" ;; *) echo "Running beet import..." beet import "$IMPORT_DIR" ;; esac # Add Replay Gain information echo "Adding Replay Gain information to files..." find "$IMPORT_DIR" -type f -iname "*.flac" -exec dirname {} \; | sort -u | while read -r album_path; do echo "Processing album for ReplayGain: $album_path" metaflac --add-replay-gain "$album_path"/*.flac done # Choose copy or move COPY_CMD="cp" $MOVE_FILES && COPY_CMD="mv" # === Process FLAC files === find "$IMPORT_DIR" -type f -name "*.flac" | while read -r file; do original_artist="${ORIGINAL_ARTIST_MAP["$file"]}" original_album="${ORIGINAL_ALBUM_MAP["$file"]}" updated_artist=$(metaflac --show-tag=ALBUMARTIST "$file" | sed 's/^ALBUMARTIST=//') updated_album=$(metaflac --show-tag=ALBUM "$file" | sed 's/^ALBUM=//') [[ "$original_artist" != "$updated_artist" ]] && resolved_artist="$original_artist ($updated_artist)" || resolved_artist="$original_artist" [[ "$original_album" != "$updated_album" ]] && resolved_album="$original_album ($updated_album)" || resolved_album="$original_album" target_dir="$LIBRARY_DIR/$resolved_artist/$resolved_album" mkdir -p "$target_dir" $COPY_CMD "$file" "$target_dir/" echo "$COPY_CMD $file to $target_dir" done # === Process album cover images === find "$IMPORT_DIR" -type f \( -iname "*.jpg" -o -iname "*.png" \) | while read -r img_file; do dir_path=$(dirname "$img_file") first_flac=$(find "$dir_path" -maxdepth 1 -type f -iname "*.flac" | head -n 1) if [[ -z "$first_flac" ]]; then echo "No FLAC file found in $dir_path to extract metadata from. Skipping image: $img_file" continue fi original_artist="${ORIGINAL_ARTIST_MAP["$first_flac"]}" original_album="${ORIGINAL_ALBUM_MAP["$first_flac"]}" updated_artist=$(metaflac --show-tag=ALBUMARTIST "$first_flac" | sed 's/^ALBUMARTIST=//') updated_album=$(metaflac --show-tag=ALBUM "$first_flac" | sed 's/^ALBUM=//') [[ "$original_artist" != "$updated_artist" ]] && resolved_artist="$original_artist ($updated_artist)" || resolved_artist="$original_artist" [[ "$original_album" != "$updated_album" ]] && resolved_album="$original_album ($updated_album)" || resolved_album="$original_album" target_dir="$LIBRARY_DIR/$resolved_artist/$resolved_album" mkdir -p "$target_dir" $COPY_CMD "$img_file" "$target_dir/" echo "$COPY_CMD $img_file to $target_dir" done # === Process artist images (e.g. artist.jpg) === find "$IMPORT_DIR" -mindepth 2 -maxdepth 2 -type f \( -iname "artist.jpg" -o -iname "artist.png" \) | while read -r artist_img; do artist_dir_path=$(dirname "$artist_img") artist_name=$(basename "$artist_dir_path") flac_file=$(find "$artist_dir_path" -type f -iname "*.flac" | head -n 1) if [[ -n "$flac_file" ]]; then updated_artist=$(metaflac --show-tag=ALBUMARTIST "$flac_file" | sed 's/^ALBUMARTIST=//') [[ "$artist_name" != "$updated_artist" ]] && resolved_artist="$artist_name ($updated_artist)" || resolved_artist="$artist_name" else resolved_artist="$artist_name" fi target_dir="$LIBRARY_DIR/$resolved_artist" mkdir -p "$target_dir" $COPY_CMD "$artist_img" "$target_dir/" echo "$COPY_CMD $artist_img to $target_dir" done echo "Import completed."