#!/usr/bin/env bash set -euo pipefail SCRIPT=$(basename "$0") LAUNCHER=('rofi' '-theme-str' 'window {width: 20%;}' '-dmenu' '-c' '-l' '4' '-p') MUSIC_DIR="${XDG_MUSIC_DIR:-$HOME/Music}" if [[ ! -d "$MUSIC_DIR" ]]; then notify-send -u critical "Error" "Music directory not found: $MUSIC_DIR" exit 1 fi music_files=$(find -L "$MUSIC_DIR" -type f \( \ -iname "*.mp3" -o \ -iname "*.flac" -o \ -iname "*.wav" -o \ -iname "*.ogg" -o \ -iname "*.m4a" -o \ -iname "*.aac" -o \ -iname "*.opus" -o \ -iname "*.wma" \ \) 2>/dev/null | sed "s|^$MUSIC_DIR/||") list_archive_music() { local archive_path="$1" local archive_rel_path="$2" local music_pattern='\.(mp3|flac|wav|ogg|m4a|aac|opus|wma)$' case "${archive_path,,}" in *.zip) if command -v unzip >/dev/null 2>&1; then unzip -l "$archive_path" 2>/dev/null | \ awk 'NR>3 {print $NF}' | \ grep -iE "$music_pattern" | \ sed "s|^|$archive_rel_path/|" fi ;; *.rar) if command -v unrar >/dev/null 2>&1; then unrar lb "$archive_path" 2>/dev/null | \ grep -iE "$music_pattern" | \ sed "s|^|$archive_rel_path/|" fi ;; *.7z) if command -v 7z >/dev/null 2>&1; then 7z l -slt "$archive_path" 2>/dev/null | \ awk '/^Path = / {print substr($0, 8)}' | \ grep -iE "$music_pattern" | \ sed "s|^|$archive_rel_path/|" fi ;; *.tar|*.tar.gz|*.tar.bz2|*.tar.xz) if command -v tar >/dev/null 2>&1; then tar -tf "$archive_path" 2>/dev/null | \ grep -iE "$music_pattern" | \ sed "s|^|$archive_rel_path/|" fi ;; esac } archive_music_files="" while IFS= read -r -d '' archive_file; do archive_rel_path=$(echo "$archive_file" | sed "s|^$MUSIC_DIR/||") archive_music=$(list_archive_music "$archive_file" "$archive_rel_path") if [[ -n "$archive_music" ]]; then archive_music_files="$archive_music_files$archive_music"$'\n' fi done < <(find -L "$MUSIC_DIR" -type f \( \ -iname "*.zip" -o \ -iname "*.rar" -o \ -iname "*.7z" -o \ -iname "*.tar" -o \ -iname "*.tar.gz" -o \ -iname "*.tar.bz2" -o \ -iname "*.tar.xz" \ \) -print0 2>/dev/null) all_music_files="" if [[ -n "$music_files" ]]; then all_music_files="$music_files" fi if [[ -n "$archive_music_files" ]]; then if [[ -n "$all_music_files" ]]; then all_music_files="$all_music_files"$'\n'"$archive_music_files" else all_music_files="$archive_music_files" fi fi all_music_files=$(echo "$all_music_files" | grep -v '^$' | sort) if [[ -z "$all_music_files" ]]; then notify-send -u normal "Info" "No music files found in $MUSIC_DIR" exit 0 fi selection=$(echo "$all_music_files" | "${LAUNCHER[@]}" "Select song:") if [[ -z "$selection" ]]; then exit 0 fi if rmpc add "$selection"; then notify-send -u normal "Music" "Added: $(basename "$selection")" else notify-send -u critical "Error" "Failed to add: $(basename "$selection")" exit 1 fi