111 lines
3.2 KiB
Bash
Raw Permalink Normal View History

2026-03-09 00:07:31 -04:00
#!/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