111 lines
3.2 KiB
Bash
111 lines
3.2 KiB
Bash
|
|
#!/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
|