initial commit
This commit is contained in:
commit
503856e135
18
LICENSE
Normal file
18
LICENSE
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
MIT No Attribution
|
||||||
|
|
||||||
|
Copyright 2024 teraflops
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
60
README.md
Normal file
60
README.md
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# mympc
|
||||||
|
|
||||||
|
## Wrapper around the [mpc](https://musicpd.org/clients/mpc/) command line client for controlling a [Music Player Daemon](https://musicpd.org/) server.
|
||||||
|
|
||||||
|
It does zsh completion for the mpc command and provides a few functions to make it easier to use mpc.
|
||||||
|
|
||||||
|
### Installation.
|
||||||
|
|
||||||
|
copy the files in the same path as they are in the repo. Add the following to your .zshrc file:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
autoload -Uz compinit
|
||||||
|
compinit
|
||||||
|
```
|
||||||
|
```bash
|
||||||
|
Usage: /usr/local/bin/mympc [options] [arguments]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--artist [name] Search for songs by artist (comma-separated)
|
||||||
|
--genre [name] Search for songs by genre
|
||||||
|
--album [name] Search for songs by album
|
||||||
|
--track [name] Search for songs by track name (comma-separated)
|
||||||
|
--year [year] Search for songs by release year (e.g., --year=1990)
|
||||||
|
--duration [min:sec] Search for songs by duration (e.g., --duration=3:30)
|
||||||
|
-n, --number [number] Specify the number of songs to add to the playlist (default: 15)
|
||||||
|
--play Play directly after adding songs to the playlist
|
||||||
|
--preview Preview the songs that will be added to the playlist without adding them
|
||||||
|
--save-playlist [name] Save the current playlist with the given name
|
||||||
|
--remove [track1,track2,...] Remove one or more songs from the playlist, separated by commas
|
||||||
|
--list-artists List all available artists
|
||||||
|
--list-genres List all available genres
|
||||||
|
--list-albums List all available albums
|
||||||
|
--random Activate random mode
|
||||||
|
--repeat Activate repeat mode
|
||||||
|
--get-rating Get the rating of the current song
|
||||||
|
--rate [0-5] Set the rating of the current song (0-5)
|
||||||
|
--toprated Generate a playlist of top-rated songs (rating=5)
|
||||||
|
--add-tag [key=value] Add a custom tag to the current song
|
||||||
|
--delete-tag [key] Delete a custom tag from the current song
|
||||||
|
--list-tags List all tags of the current song
|
||||||
|
--update-tag [key=value] Update a custom tag of the current song
|
||||||
|
--playlist-by-mood [mood] Generate a playlist based on the specified mood
|
||||||
|
--playlist-by-mood=[mood] Same as above, using '=' syntax
|
||||||
|
--help, -h Show this help message
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
/usr/local/bin/mympc --artist="Pink Floyd,AC/DC" --play -n 10
|
||||||
|
/usr/local/bin/mympc --album="The Dark Side of the Moon" --play
|
||||||
|
/usr/local/bin/mympc --genre="Blues" --year=1980 --play -n 5
|
||||||
|
/usr/local/bin/mympc --track="Comfortably Numb,Money" --play
|
||||||
|
/usr/local/bin/mympc --artist="Pink Floyd" --track="Money,Time" --play
|
||||||
|
/usr/local/bin/mympc --get-rating
|
||||||
|
/usr/local/bin/mympc --rate 4
|
||||||
|
/usr/local/bin/mympc --toprated --play
|
||||||
|
/usr/local/bin/mympc --add-tag "mood=happy"
|
||||||
|
/usr/local/bin/mympc --delete-tag "mood"
|
||||||
|
/usr/local/bin/mympc --list-tags
|
||||||
|
/usr/local/bin/mympc --update-tag "mood=energetic"
|
||||||
|
/usr/local/bin/mympc --playlist-by-mood=happy --play
|
||||||
|
```
|
635
usr/local/bin/mympc
Executable file
635
usr/local/bin/mympc
Executable file
@ -0,0 +1,635 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# mympc: A script to interact with mpc in an efficient and flexible way.
|
||||||
|
|
||||||
|
# ========================
|
||||||
|
# Initial Setup
|
||||||
|
# ========================
|
||||||
|
|
||||||
|
# Source centralized tag definitions
|
||||||
|
# Ensure that /usr/local/share/mympc/tags.sh exists and is properly configured
|
||||||
|
if [[ -f /usr/local/share/mympc/tags.sh ]]; then
|
||||||
|
source /usr/local/share/mympc/tags.sh
|
||||||
|
else
|
||||||
|
echo "Error: /usr/local/share/mympc/tags.sh not found. Please create it with necessary tag definitions."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Function to display help message
|
||||||
|
show_help() {
|
||||||
|
cat << EOF
|
||||||
|
Usage: $0 [options] [arguments]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--artist [name] Search for songs by artist
|
||||||
|
--genre [name] Search for songs by genre
|
||||||
|
--album [name] Search for songs by album
|
||||||
|
--track [name] Search for songs by track name
|
||||||
|
--year [year] Search for songs by release year (e.g., --year=1990)
|
||||||
|
--duration [min:sec] Search for songs by duration (e.g., --duration=3:30)
|
||||||
|
-n, --number [number] Specify the number of songs to add to the playlist (default: 15)
|
||||||
|
--play Play directly after adding songs to the playlist
|
||||||
|
--preview Preview the songs that will be added to the playlist without adding them
|
||||||
|
--save-playlist [name] Save the current playlist with the given name
|
||||||
|
--remove [track1,track2,...] Remove one or more songs from the playlist, separated by commas
|
||||||
|
--list-artists List all available artists
|
||||||
|
--list-genres List all available genres
|
||||||
|
--list-albums List all available albums
|
||||||
|
--random Activate random mode
|
||||||
|
--repeat Activate repeat mode
|
||||||
|
--get-rating Get the rating of the current song
|
||||||
|
--rate [0-5] Set the rating of the current song (0-5)
|
||||||
|
--toprated Generate a playlist of top-rated songs (rating=5)
|
||||||
|
--add-tag [key=value] Add a custom tag to the current song
|
||||||
|
--delete-tag [key] Delete a custom tag from the current song
|
||||||
|
--list-tags List all tags of the current song
|
||||||
|
--update-tag [key=value] Update a custom tag of the current song
|
||||||
|
--playlist-by-mood [mood] Generate a playlist based on the specified mood
|
||||||
|
--help, -h Show this help message
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
$0 --artist="Pink Floyd,AC/DC" --play -n 10
|
||||||
|
$0 --album="The Dark Side of the Moon" --play
|
||||||
|
$0 --genre="Blues" --year=1980 --play -n 5
|
||||||
|
$0 --track="Comfortably Numb,Money" --play
|
||||||
|
$0 --artist="Pink Floyd" --track="Money,Time" --play
|
||||||
|
$0 --get-rating
|
||||||
|
$0 --rate 4
|
||||||
|
$0 --toprated --play
|
||||||
|
$0 --add-tag "mood=happy"
|
||||||
|
$0 --delete-tag "mood"
|
||||||
|
$0 --list-tags
|
||||||
|
$0 --update-tag "mood=energetic"
|
||||||
|
$0 --playlist-by-mood=happy --play
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to get the URI of the current song
|
||||||
|
get_current_song_uri() {
|
||||||
|
mpc --format %file% current
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if a tag exists on a song
|
||||||
|
tag_exists() {
|
||||||
|
local song="$1"
|
||||||
|
local key="$2"
|
||||||
|
mpc sticker "$song" list 2>/dev/null | cut -d'=' -f1 | grep -qw "$key"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if a value is in an array
|
||||||
|
is_in_array() {
|
||||||
|
local element
|
||||||
|
for element in "${@:2}"; do
|
||||||
|
[[ "$element" == "$1" ]] && return 0
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_song_from_playlist() {
|
||||||
|
local position="$1"
|
||||||
|
|
||||||
|
# Validate that position is a positive integer
|
||||||
|
if ! [[ "$position" =~ ^[1-9][0-9]*$ ]]; then
|
||||||
|
echo "Error: Position must be a positive integer."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Delete the song at the specified position
|
||||||
|
if mpc del "$position"; then
|
||||||
|
echo "Song at position $position deleted from the playlist."
|
||||||
|
else
|
||||||
|
echo "Error: Failed to delete song at position $position."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ========================
|
||||||
|
# Initialize Variables
|
||||||
|
# ========================
|
||||||
|
|
||||||
|
number_of_songs=15
|
||||||
|
play_now=false
|
||||||
|
preview=false
|
||||||
|
declare -A search_params
|
||||||
|
artists=()
|
||||||
|
genres=()
|
||||||
|
albums=()
|
||||||
|
tracks=()
|
||||||
|
years=()
|
||||||
|
durations=()
|
||||||
|
remove_songs=()
|
||||||
|
playlist_name=""
|
||||||
|
get_rating=false
|
||||||
|
set_rating_value=""
|
||||||
|
toprated=false
|
||||||
|
|
||||||
|
# Tag-related variables
|
||||||
|
add_tag=""
|
||||||
|
delete_tag=""
|
||||||
|
list_tags=false
|
||||||
|
update_tag=""
|
||||||
|
|
||||||
|
# Playlist by mood variables
|
||||||
|
mood_value=""
|
||||||
|
playlist_name_override=""
|
||||||
|
|
||||||
|
# ========================
|
||||||
|
# Option Parsing with getopt
|
||||||
|
# ========================
|
||||||
|
|
||||||
|
# Define the options
|
||||||
|
TEMP=$(getopt -o n:h --long artist:,genre:,album:,track:,year:,duration:,number:,play,preview,save-playlist:,remove:,list-artists,list-genres,list-albums,random,repeat,get-rating,rate:,toprated,add-tag:,delete-tag:,list-tags,update-tag:,playlist-by-mood:,playlist-by-mood,help -n "$0" -- "$@")
|
||||||
|
|
||||||
|
# Check if getopt succeeded
|
||||||
|
if [ $? != 0 ] ; then show_help; exit 1 ; fi
|
||||||
|
|
||||||
|
# Reorder the arguments
|
||||||
|
eval set -- "$TEMP"
|
||||||
|
|
||||||
|
# Parse the options
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
--artist)
|
||||||
|
if [[ -n "${search_params[genre]}" || -n "${search_params[artist]}" ]]; then
|
||||||
|
echo "Error: --artist cannot be used with --genre or multiple times."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
# Usar eval para manejar correctamente las comillas y espacios
|
||||||
|
artist_names=$(eval echo "$1")
|
||||||
|
IFS=',' read -ra ARTISTS_ARRAY <<< "$artist_names"
|
||||||
|
for artist in "${ARTISTS_ARRAY[@]}"; do
|
||||||
|
artist=$(echo "$artist" | xargs)
|
||||||
|
if [[ "$artist" =~ [^a-zA-Z0-9\ \.\,\&\'\-\/] ]]; then
|
||||||
|
echo "Error: Artist names can only contain letters, numbers, spaces, and characters like .,&,',-,/."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
artists+=("$artist")
|
||||||
|
done
|
||||||
|
search_params[artist]=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--genre)
|
||||||
|
if [[ -n "${search_params[artist]}" || -n "${search_params[album]}" || -n "${search_params[genre]}" ]]; then
|
||||||
|
echo "Error: --genre cannot be used with --artist, --album, or multiple times."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
genres+=("$1")
|
||||||
|
search_params[genre]=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--album)
|
||||||
|
if [[ -n "${search_params[genre]}" || -n "${search_params[album]}" || -n "${search_params[number]}" ]]; then
|
||||||
|
echo "Error: --album cannot be used with --genre, --number, or multiple times."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
# Usar un enfoque más robusto para manejar comillas y apóstrofes
|
||||||
|
album_name="$1"
|
||||||
|
# Escapar solo lo necesario para mpc sin usar eval
|
||||||
|
albums+=("$album_name")
|
||||||
|
search_params[album]=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
--track)
|
||||||
|
if [[ -n "${search_params[track]}" ]]; then
|
||||||
|
echo "Error: --track cannot be used multiple times."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
track_names="$1"
|
||||||
|
IFS=',' read -ra TRACKS_ARRAY <<< "$track_names"
|
||||||
|
for track in "${TRACKS_ARRAY[@]}"; do
|
||||||
|
track=$(echo "$track" | xargs)
|
||||||
|
if [[ "$track" =~ [^a-zA-Z0-9\ \.\,\&\'\-\/] ]]; then
|
||||||
|
echo "Error: Track names can only contain letters, numbers, spaces, and characters like .,&,',-,/."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
tracks+=("$track")
|
||||||
|
done
|
||||||
|
search_params[track]=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--year)
|
||||||
|
if [[ -n "${search_params[year]}" ]]; then
|
||||||
|
echo "Error: --year cannot be used multiple times."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
if ! [[ "$1" =~ ^(19|20)[0-9]{2}$ ]]; then
|
||||||
|
echo "Error: --year must be a valid year (e.g., 1990)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
years+=("$1")
|
||||||
|
search_params[year]=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--duration)
|
||||||
|
if [[ -n "${search_params[duration]}" ]]; then
|
||||||
|
echo "Error: --duration cannot be used multiple times."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
if ! [[ "$1" =~ ^([0-9]+):([0-5][0-9])$ ]]; then
|
||||||
|
echo "Error: --duration must be in the format min:sec (e.g., 3:30)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
durations+=("$1")
|
||||||
|
search_params[duration]=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-n|--number)
|
||||||
|
if [[ -n "${search_params[album]}" || "$toprated" = true || -n "${search_params[number]}" ]]; then
|
||||||
|
echo "Error: --number cannot be used with --album, --toprated, or multiple times."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
number_of_songs="$1"
|
||||||
|
if ! [[ "$number_of_songs" =~ ^[1-9][0-9]*$ ]]; then
|
||||||
|
echo "Error: --number must be a positive integer."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
search_params[number]=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--play)
|
||||||
|
play_now=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--preview)
|
||||||
|
preview=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--save-playlist)
|
||||||
|
shift
|
||||||
|
playlist_name_override="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--remove)
|
||||||
|
shift
|
||||||
|
delete_song="$1"
|
||||||
|
shift
|
||||||
|
# Parse the position from "position: song name"
|
||||||
|
if [[ "$delete_song" =~ ^([0-9]+):\ (.+)$ ]]; then
|
||||||
|
delete_position="${BASH_REMATCH[1]}"
|
||||||
|
delete_song_name="${BASH_REMATCH[2]}"
|
||||||
|
else
|
||||||
|
echo "Error: Invalid format for --remove. Expected 'position: song name'."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# Call the function to delete the song from the playlist
|
||||||
|
delete_song_from_playlist "$delete_position"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--list-artists)
|
||||||
|
mpc list artist
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--list-genres)
|
||||||
|
mpc list genre
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--list-albums)
|
||||||
|
mpc list album
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--random)
|
||||||
|
mpc random on
|
||||||
|
echo "Random mode activated."
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--repeat)
|
||||||
|
mpc repeat on
|
||||||
|
echo "Repeat mode activated."
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--get-rating)
|
||||||
|
get_rating=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--rate)
|
||||||
|
if [[ -n "$set_rating_value" ]]; then
|
||||||
|
echo "Error: --rate cannot be used multiple times."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
set_rating_value="$1"
|
||||||
|
if ! [[ "$set_rating_value" =~ ^[0-5]$ ]]; then
|
||||||
|
echo "Error: Rating must be between 0 and 5."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--toprated)
|
||||||
|
if [[ -n "${search_params[number]}" || "$toprated" = true ]]; then
|
||||||
|
echo "Error: --toprated cannot be used with --number or multiple times."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
toprated=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--add-tag)
|
||||||
|
shift
|
||||||
|
add_tag="$1"
|
||||||
|
# Validate the format key=value
|
||||||
|
if ! [[ "$add_tag" =~ ^[^=]+=[^=]+$ ]]; then
|
||||||
|
echo "Error: --add-tag must be in the format key=value."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--delete-tag)
|
||||||
|
shift
|
||||||
|
delete_tag="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--playlist-by-mood=*)
|
||||||
|
mood_value="${key#*=}"
|
||||||
|
# Invoke the Python script to handle playlist generation
|
||||||
|
/usr/local/share/mympc/add_mood_tag.py "$mood_value"
|
||||||
|
shift # past argument
|
||||||
|
;;
|
||||||
|
--playlist-by-mood)
|
||||||
|
mood_value="$2"
|
||||||
|
# Invoke the Python script to handle playlist generation
|
||||||
|
/usr/local/share/mympc/add_mood_tag.py "$mood_value"
|
||||||
|
shift # past argument
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--list-tags)
|
||||||
|
# Handle --list-tags
|
||||||
|
list_tags=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--update-tag)
|
||||||
|
shift
|
||||||
|
update_tag="$1"
|
||||||
|
# Validate the format key=value
|
||||||
|
if ! [[ "$update_tag" =~ ^[^=]+=[^=]+$ ]]; then
|
||||||
|
echo "Error: --update-tag must be in the format key=value."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--help|-h)
|
||||||
|
show_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid option: $1"
|
||||||
|
echo "Use --help to see available options."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# ========================
|
||||||
|
# Execute Tag Actions
|
||||||
|
# ========================
|
||||||
|
|
||||||
|
# Verify if mpc supports the sticker command
|
||||||
|
if ! mpc help | grep -q 'sticker'; then
|
||||||
|
echo "Error: Your mpc version does not support the sticker command."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# List all tags of the current song
|
||||||
|
if [ "$list_tags" = true ]; then
|
||||||
|
song_uri=$(get_current_song_uri)
|
||||||
|
if [[ -z "$song_uri" ]]; then
|
||||||
|
echo "No song is currently playing."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
tags=$(mpc sticker "$song_uri" list 2>/dev/null)
|
||||||
|
if [ -z "$tags" ]; then
|
||||||
|
echo "No tags found for the current song."
|
||||||
|
else
|
||||||
|
echo "Tags for '$song_uri':"
|
||||||
|
echo "$tags"
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add a custom tag to the current song
|
||||||
|
if [ -n "$add_tag" ]; then
|
||||||
|
song_uri=$(get_current_song_uri)
|
||||||
|
if [[ -z "$song_uri" ]]; then
|
||||||
|
echo "Error: No song is currently playing."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
key="${add_tag%%=*}"
|
||||||
|
value="${add_tag#*=}"
|
||||||
|
|
||||||
|
# Validate the key and value
|
||||||
|
if [[ "$key" == "mood" ]]; then
|
||||||
|
if ! is_in_array "$value" "${allowed_moods[@]}"; then
|
||||||
|
echo "Error: Invalid mood value '$value'. Allowed values are: ${allowed_moods[*]}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif [[ " ${allowed_custom_tags[*]} " != *" $key "* ]]; then
|
||||||
|
echo "Error: Invalid tag key '$key'. Allowed keys are: ${allowed_custom_tags[*]}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mpc sticker "$song_uri" set "$key" "$value"
|
||||||
|
echo "Tag '$key=$value' added to '$song_uri'."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Delete a custom tag from the current song
|
||||||
|
if [ -n "$delete_tag" ]; then
|
||||||
|
song_uri=$(get_current_song_uri)
|
||||||
|
if [[ -z "$song_uri" ]]; then
|
||||||
|
echo "Error: No song is currently playing."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if tag_exists "$song_uri" "$delete_tag"; then
|
||||||
|
mpc sticker "$song_uri" delete "$delete_tag"
|
||||||
|
echo "Tag '$delete_tag' deleted from '$song_uri'."
|
||||||
|
else
|
||||||
|
echo "Error: Tag '$delete_tag' does not exist on '$song_uri'."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update a custom tag of the current song
|
||||||
|
if [ -n "$update_tag" ]; then
|
||||||
|
song_uri=$(get_current_song_uri)
|
||||||
|
if [[ -z "$song_uri" ]]; then
|
||||||
|
echo "Error: No song is currently playing."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
key="${update_tag%%=*}"
|
||||||
|
value="${update_tag#*=}"
|
||||||
|
|
||||||
|
# Validate the key and value
|
||||||
|
if [[ "$key" == "mood" ]]; then
|
||||||
|
if ! is_in_array "$value" "${allowed_moods[@]}"; then
|
||||||
|
echo "Error: Invalid mood value '$value'. Allowed values are: ${allowed_moods[*]}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif [[ " ${allowed_custom_tags[*]} " != *" $key "* ]]; then
|
||||||
|
echo "Error: Invalid tag key '$key'. Allowed keys are: ${allowed_custom_tags[*]}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if tag_exists "$song_uri" "$key"; then
|
||||||
|
mpc sticker "$song_uri" set "$key" "$value"
|
||||||
|
echo "Tag '$key' updated to '$value' in '$song_uri'."
|
||||||
|
else
|
||||||
|
echo "Error: Tag '$key' does not exist on '$song_uri'. Use --add-tag to add it."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ========================
|
||||||
|
# Execute Rating Actions
|
||||||
|
# ========================
|
||||||
|
|
||||||
|
if [ "$get_rating" = true ]; then
|
||||||
|
song_uri=$(get_current_song_uri)
|
||||||
|
if [[ -z "$song_uri" ]]; then
|
||||||
|
echo "No song is currently playing."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
rating=$(mpc sticker "$song_uri" get rating 2>/dev/null | sed 's/^rating=//')
|
||||||
|
if [ -z "$rating" ]; then
|
||||||
|
echo "No rating found for the current song."
|
||||||
|
else
|
||||||
|
echo "Rating of '$song_uri' is: $rating"
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$set_rating_value" ]; then
|
||||||
|
song_uri=$(get_current_song_uri)
|
||||||
|
if [[ -z "$song_uri" ]]; then
|
||||||
|
echo "Error: No song is currently playing."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
mpc sticker "$song_uri" set rating "$set_rating_value"
|
||||||
|
echo "Rating of '$song_uri' set to $set_rating_value."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ========================
|
||||||
|
# Final Validation
|
||||||
|
# ========================
|
||||||
|
|
||||||
|
if [ "$toprated" = false ] && [ "${#search_params[@]}" -eq 0 ]; then
|
||||||
|
echo "Error: You must specify at least one search criteria."
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ========================
|
||||||
|
# Build the Search Command
|
||||||
|
# ========================
|
||||||
|
|
||||||
|
# Clear the current playlist
|
||||||
|
mpc clear
|
||||||
|
|
||||||
|
if [ "$toprated" = true ]; then
|
||||||
|
# Call the Python script to get top-rated tracks
|
||||||
|
# Ensure that /usr/local/share/mympc/get_top_rated_tracks.py exists and is executable
|
||||||
|
if [ ! -x /usr/local/share/mympc/get_top_rated_tracks.py ]; then
|
||||||
|
echo "Error: Python script '/usr/local/share/mympc/get_top_rated_tracks.py' not found or not executable."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
python3 /usr/local/share/mympc/get_top_rated_tracks.py
|
||||||
|
if [ "$play_now" = true ]; then
|
||||||
|
mpc play
|
||||||
|
echo "Playing playlist."
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Construct the search command
|
||||||
|
search_cmd="mpc search"
|
||||||
|
|
||||||
|
for key in "${!search_params[@]}"; do
|
||||||
|
if [[ "$key" == "artist" ]]; then
|
||||||
|
for artist in "${artists[@]}"; do
|
||||||
|
# Escapar comillas internas y mantener las externas para mpc
|
||||||
|
artist_escaped="${artist//\"/\\\"}"
|
||||||
|
search_cmd+=" artist \"$artist_escaped\""
|
||||||
|
done
|
||||||
|
elif [[ "$key" == "genre" ]]; then
|
||||||
|
for genre in "${genres[@]}"; do
|
||||||
|
genre_escaped="${genre//\"/\\\"}"
|
||||||
|
search_cmd+=" genre \"$genre_escaped\""
|
||||||
|
done
|
||||||
|
elif [[ "$key" == "album" ]]; then
|
||||||
|
for album in "${albums[@]}"; do
|
||||||
|
album_escaped="${album//\"/\\\"}"
|
||||||
|
search_cmd+=" album \"$album_escaped\""
|
||||||
|
done
|
||||||
|
elif [[ "$key" == "track" ]]; then
|
||||||
|
for track in "${tracks[@]}"; do
|
||||||
|
track_escaped="${track//\"/\\\"}"
|
||||||
|
search_cmd+=" title \"$track_escaped\""
|
||||||
|
done
|
||||||
|
elif [[ "$key" == "year" ]]; then
|
||||||
|
for year in "${years[@]}"; do
|
||||||
|
search_cmd+=" date \"$year\""
|
||||||
|
done
|
||||||
|
elif [[ "$key" == "duration" ]]; then
|
||||||
|
for duration in "${durations[@]}"; do
|
||||||
|
search_cmd+=" duration \"$duration\""
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Debugging: print the search command (uncomment if needed)
|
||||||
|
# echo "Executing search command: $search_cmd"
|
||||||
|
|
||||||
|
# Execute the search command and capture the songs
|
||||||
|
songs=$(eval "$search_cmd")
|
||||||
|
|
||||||
|
if [ -z "$songs" ]; then
|
||||||
|
echo "No songs found with the specified criteria."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
if [[ -n "${search_params[album]}" || -n "${search_params[track]}" ]]; then
|
||||||
|
# Add all found songs to the playlist
|
||||||
|
echo "$songs" | mpc add
|
||||||
|
num_songs_added=$(echo "$songs" | wc -l)
|
||||||
|
echo "Added $num_songs_added song(s) to the playlist."
|
||||||
|
else
|
||||||
|
# Add a random subset of songs to the playlist
|
||||||
|
selected_songs=$(echo "$songs" | shuf -n"$number_of_songs")
|
||||||
|
echo "$selected_songs" | mpc add
|
||||||
|
num_songs_added=$(echo "$selected_songs" | wc -l)
|
||||||
|
echo "Added $num_songs_added song(s) to the playlist."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ========================
|
||||||
|
# Save Playlist
|
||||||
|
# ========================
|
||||||
|
|
||||||
|
if [ -n "$playlist_name" ]; then
|
||||||
|
mpc save "$playlist_name"
|
||||||
|
echo "Playlist saved as '$playlist_name'."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ========================
|
||||||
|
# Play Playlist
|
||||||
|
# ========================
|
||||||
|
|
||||||
|
if [ "$play_now" = true ]; then
|
||||||
|
mpc play
|
||||||
|
echo "Playing playlist."
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
122
usr/local/share/mympc/add_mood_tag.py
Executable file
122
usr/local/share/mympc/add_mood_tag.py
Executable file
@ -0,0 +1,122 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
from mpd import MPDClient, CommandError
|
||||||
|
import random
|
||||||
|
|
||||||
|
# Define the list of allowed mood tags
|
||||||
|
ALLOWED_MOOD_TAGS = {
|
||||||
|
"happy",
|
||||||
|
"sad",
|
||||||
|
"energetic",
|
||||||
|
"calm",
|
||||||
|
"angry",
|
||||||
|
"relaxed",
|
||||||
|
"excited",
|
||||||
|
"melancholic"
|
||||||
|
}
|
||||||
|
|
||||||
|
def parse_arguments():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Add songs with a specified mood tag to the MPD playlist."
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"mood",
|
||||||
|
type=str,
|
||||||
|
help=f"Desired mood tag. Allowed values: {', '.join(sorted(ALLOWED_MOOD_TAGS))}"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--host",
|
||||||
|
type=str,
|
||||||
|
default="localhost",
|
||||||
|
help="MPD server host (default: localhost)"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--port",
|
||||||
|
type=int,
|
||||||
|
default=6600,
|
||||||
|
help="MPD server port (default: 6600)"
|
||||||
|
)
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
def add_tracks_by_mood(mood, host="localhost", port=6600):
|
||||||
|
mood = mood.lower()
|
||||||
|
if mood not in ALLOWED_MOOD_TAGS:
|
||||||
|
print(f"Error: Invalid mood '{mood}'. Allowed moods are: {', '.join(sorted(ALLOWED_MOOD_TAGS))}.", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
client = MPDClient()
|
||||||
|
try:
|
||||||
|
# Connect to the MPD server
|
||||||
|
client.connect(host, port)
|
||||||
|
print(f"Connected to MPD server at {host}:{port}.")
|
||||||
|
|
||||||
|
# Clear the current playlist
|
||||||
|
client.clear()
|
||||||
|
print("Cleared the current playlist.")
|
||||||
|
|
||||||
|
# Search for songs with the specified mood tag
|
||||||
|
# Assuming 'mood' is stored as a sticker in the format 'mood=<tag>'
|
||||||
|
# Using sticker_find to search for songs with the 'mood' sticker
|
||||||
|
response = client.sticker_find('song', '', 'mood')
|
||||||
|
|
||||||
|
# Process the response to filter tracks with the specified mood tag
|
||||||
|
matching_tracks = []
|
||||||
|
for entry in response:
|
||||||
|
file_path = entry.get('file')
|
||||||
|
sticker = entry.get('sticker')
|
||||||
|
if file_path and sticker:
|
||||||
|
try:
|
||||||
|
sticker_key, sticker_value = sticker.split('=', 1)
|
||||||
|
if sticker_key == 'mood' and sticker_value.lower() == mood:
|
||||||
|
matching_tracks.append(file_path)
|
||||||
|
except ValueError:
|
||||||
|
# Skip malformed sticker entries
|
||||||
|
continue
|
||||||
|
|
||||||
|
if matching_tracks:
|
||||||
|
# Remove duplicates
|
||||||
|
unique_tracks = sorted(set(matching_tracks))
|
||||||
|
|
||||||
|
# Shuffle songs for randomness
|
||||||
|
random.shuffle(unique_tracks)
|
||||||
|
|
||||||
|
# Add unique songs to the playlist
|
||||||
|
for track in unique_tracks:
|
||||||
|
client.add(track)
|
||||||
|
print(f"Added {len(unique_tracks)} unique song(s) with mood '{mood}' to the playlist.")
|
||||||
|
|
||||||
|
# Optionally, save the playlist with a specific name
|
||||||
|
# client.save('mood_playlist')
|
||||||
|
|
||||||
|
# Optionally, start playing the playlist
|
||||||
|
# client.play()
|
||||||
|
|
||||||
|
sys.exit(0) # Success
|
||||||
|
else:
|
||||||
|
print(f"No songs found with mood '{mood}'.")
|
||||||
|
sys.exit(0) # Treat as success since it's not a critical error
|
||||||
|
|
||||||
|
except CommandError as ce:
|
||||||
|
print(f"MPD command error: {ce}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"An error occurred: {e}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
finally:
|
||||||
|
# Close the connection to the MPD server
|
||||||
|
try:
|
||||||
|
client.close()
|
||||||
|
client.disconnect()
|
||||||
|
print("Disconnected from MPD server.")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parse_arguments()
|
||||||
|
add_tracks_by_mood(args.mood, host=args.host, port=args.port)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
33
usr/local/share/mympc/get_top_rated_tracks.py
Executable file
33
usr/local/share/mympc/get_top_rated_tracks.py
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from mpd import MPDClient
|
||||||
|
|
||||||
|
def get_top_rated_tracks():
|
||||||
|
client = MPDClient()
|
||||||
|
client.connect("localhost", 6600) # Ajusta el host y el puerto si es necesario
|
||||||
|
|
||||||
|
# Utiliza el URI raíz o un directorio específico
|
||||||
|
response = client.sticker_find('song', '', 'rating')
|
||||||
|
|
||||||
|
# Procesar la respuesta
|
||||||
|
tracks = []
|
||||||
|
for entry in response:
|
||||||
|
if 'file' in entry and 'sticker' in entry:
|
||||||
|
sticker_name, sticker_value = entry['sticker'].split('=', 1)
|
||||||
|
if sticker_name == 'rating' and sticker_value == '5':
|
||||||
|
tracks.append(entry['file'])
|
||||||
|
|
||||||
|
if tracks:
|
||||||
|
for track in tracks:
|
||||||
|
client.add(track)
|
||||||
|
print(f"Added {len(tracks)} song(s) with a rating of 5 to the playlist.")
|
||||||
|
else:
|
||||||
|
print("there are no rated 5 songs.")
|
||||||
|
|
||||||
|
client.close()
|
||||||
|
client.disconnect()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
get_top_rated_tracks()
|
||||||
|
|
||||||
|
|
8
usr/local/share/mympc/tags.conf
Normal file
8
usr/local/share/mympc/tags.conf
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# ~/.mympc/tags.conf
|
||||||
|
|
||||||
|
# Tag keys and their possible values
|
||||||
|
mood=happy,sad,energetic,calm,angry,relaxed,excited,melancholic
|
||||||
|
genre=rock,pop,jazz,blues,classical
|
||||||
|
rating=1,2,3,4,5
|
||||||
|
# Add more tags and their values as needed
|
||||||
|
|
45
usr/local/share/mympc/tags.sh
Executable file
45
usr/local/share/mympc/tags.sh
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
# ~/.mympc/tags.sh
|
||||||
|
# ========================
|
||||||
|
# Centralized Tag Definitions for mympc
|
||||||
|
# ========================
|
||||||
|
|
||||||
|
# Array of allowed mood values
|
||||||
|
allowed_moods=(
|
||||||
|
"happy"
|
||||||
|
"sad"
|
||||||
|
"energetic"
|
||||||
|
"calm"
|
||||||
|
"angry"
|
||||||
|
"relaxed"
|
||||||
|
"excited"
|
||||||
|
"melancholic"
|
||||||
|
# Add more moods as needed
|
||||||
|
)
|
||||||
|
|
||||||
|
# Array of allowed genre values
|
||||||
|
allowed_genres=(
|
||||||
|
"rock"
|
||||||
|
"pop"
|
||||||
|
"jazz"
|
||||||
|
"blues"
|
||||||
|
"classical"
|
||||||
|
"electronic"
|
||||||
|
"hiphop"
|
||||||
|
"country"
|
||||||
|
# Add more genres as needed
|
||||||
|
)
|
||||||
|
|
||||||
|
# Array of allowed rating values (optional)
|
||||||
|
allowed_ratings=( "0" "1" "2" "3" "4" "5" )
|
||||||
|
|
||||||
|
# Array of other custom tag keys (if any)
|
||||||
|
allowed_custom_tags=(
|
||||||
|
"custom1"
|
||||||
|
"custom2"
|
||||||
|
# Add more custom tag keys as needed
|
||||||
|
)
|
||||||
|
|
||||||
|
# ========================
|
||||||
|
# End of tags.sh
|
||||||
|
# ========================
|
||||||
|
|
189
usr/local/share/zsh/site-functions/_mympc
Normal file
189
usr/local/share/zsh/site-functions/_mympc
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
#compdef mympc
|
||||||
|
|
||||||
|
# Fixed list of moods
|
||||||
|
_fixed_moods=("happy" "sad" "energetic" "calm" "angry" "relaxed" "excited" "melancholic")
|
||||||
|
|
||||||
|
_mympc() {
|
||||||
|
_arguments -s -C \
|
||||||
|
'--artist=[Search songs by artist (separated by commas)]:artist names:_my_mpc_artists' \
|
||||||
|
'--genre=[Search songs by genre]:genre name:_my_mpc_genres' \
|
||||||
|
'--album=[Search songs by album]:album name:_my_mpc_albums' \
|
||||||
|
'--track=[Search songs by track (separated by commas)]:track names:_my_mpc_tracks' \
|
||||||
|
'--year=[Filter songs by release year]:year:_mympc_years' \
|
||||||
|
'--duration=[Filter songs by duration (min:sec)]:duration:_mympc_durations' \
|
||||||
|
'--number=[Specify the number of songs]:number of songs:_mympc_number' \
|
||||||
|
'-n=[Specify the number of songs]:number of songs:_mympc_number' \
|
||||||
|
'--play[Play immediately]' \
|
||||||
|
'--preview[Preview songs to be added without adding them]' \
|
||||||
|
'--save-playlist=[Save the current playlist]:playlist name:_my_mpc_playlists' \
|
||||||
|
'--remove=[Remove songs from the playlist (separated by commas)]:songs to remove:_my_mpc_remove_songs' \
|
||||||
|
'--list-artists[List all available artists]' \
|
||||||
|
'--list-genres[List all available genres]' \
|
||||||
|
'--list-albums[List all available albums]' \
|
||||||
|
'--random[Activate random mode]' \
|
||||||
|
'--repeat[Activate repeat mode]' \
|
||||||
|
'--get-rating[Get the rating of the current song]' \
|
||||||
|
'--rate=[Set the current song rating (0-5)]:rating value (0-5):_mympc_ratings' \
|
||||||
|
'--toprated[Generate a list with top-rated tracks (5)]' \
|
||||||
|
'--add-tag=[Add a custom tag (key=value)]:custom tag:_mympc_add_tags' \
|
||||||
|
'--delete-tag=[Delete a custom tag]:tag key:_mympc_delete_tags' \
|
||||||
|
'--list-tags[List all tags of the current song]' \
|
||||||
|
'--update-tag=[Update a custom tag (key=value)]:custom tag:_mympc_update_tags' \
|
||||||
|
'--playlist-by-mood=[Generate a playlist based on mood]:mood:_my_mpc_playlist_by_mood' \
|
||||||
|
'--help[Show help message]' \
|
||||||
|
'-h[Show help message]'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Custom autocomplete functions
|
||||||
|
|
||||||
|
_my_mpc_artists() {
|
||||||
|
compadd -- ${(f)"$(mpc list artist)"}
|
||||||
|
}
|
||||||
|
|
||||||
|
_my_mpc_genres() {
|
||||||
|
compadd -- ${(f)"$(mpc list genre)"}
|
||||||
|
}
|
||||||
|
|
||||||
|
_my_mpc_albums() {
|
||||||
|
local artist=""
|
||||||
|
local -a albums
|
||||||
|
|
||||||
|
# Buscar el artista en los argumentos ya escritos
|
||||||
|
for arg in ${words[@]}; do
|
||||||
|
if [[ $arg =~ --artist= ]]; then
|
||||||
|
# Extraer el nombre del artista (manejando espacios escapados)
|
||||||
|
artist=${arg#--artist=}
|
||||||
|
artist=${artist//\\ / }
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -n $artist ]]; then
|
||||||
|
# Obtener álbumes específicos del artista (manejando comillas)
|
||||||
|
albums=(${(f)"$(mpc list album artist "$artist")"})
|
||||||
|
else
|
||||||
|
# Obtener todos los álbumes si no hay artista especificado
|
||||||
|
albums=(${(f)"$(mpc list album)"})
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Mostrar los álbumes como opciones de completado
|
||||||
|
_describe 'album' albums
|
||||||
|
}
|
||||||
|
_my_mpc_tracks() {
|
||||||
|
compadd -- ${(f)"$(mpc list title)"}
|
||||||
|
}
|
||||||
|
|
||||||
|
_my_mpc_playlists() {
|
||||||
|
compadd -- ${(f)"$(mpc lsplaylists)"}
|
||||||
|
}
|
||||||
|
_my_mpc_remove_songs() {
|
||||||
|
# Define arrays for predefined tag values if needed
|
||||||
|
local _fixed_moods=("happy" "sad" "energetic" "calm" "angry" "relaxed" "excited" "melancholic")
|
||||||
|
local _fixed_genres=("rock" "pop" "jazz" "blues" "classical" "hiphop" "electronic")
|
||||||
|
local _fixed_ratings=("1" "2" "3" "4" "5")
|
||||||
|
|
||||||
|
# Fetch the playlist with position and title
|
||||||
|
local IFS=$'\n' # Handle song titles with spaces
|
||||||
|
local songs=($(mpc playlist -f "%position%: %title%"))
|
||||||
|
|
||||||
|
# Initialize an array for completions
|
||||||
|
local -a completions
|
||||||
|
|
||||||
|
for song in "${songs[@]}"; do
|
||||||
|
completions+=("${song}")
|
||||||
|
done
|
||||||
|
|
||||||
|
# Provide the completions
|
||||||
|
compadd -- "${completions[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_mympc_years() {
|
||||||
|
local -a years
|
||||||
|
years=($(mpc list date | grep -E '^(19|20)[0-9]{2}$' | sort -u))
|
||||||
|
compadd -- "${years[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_mympc_durations() {
|
||||||
|
compadd -- "1:00" "2:00" "3:00" "4:00" "5:00" "6:00" "7:00" "8:00" "9:00" "10:00" # Adjust durations as needed
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete for numbers
|
||||||
|
_mympc_number() {
|
||||||
|
_numbers
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete for rating values
|
||||||
|
_mympc_ratings() {
|
||||||
|
compadd -- 0 1 2 3 4 5
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete for adding tags (key=value)
|
||||||
|
_mympc_add_tags() {
|
||||||
|
# Get the current word being completed
|
||||||
|
local tag_word="${words[CURRENT]}"
|
||||||
|
|
||||||
|
# Check if the user has already typed '=' indicating key and is now completing the value
|
||||||
|
if [[ "$tag_word" == " " ]]; then
|
||||||
|
# Extract the key from 'key=value'
|
||||||
|
local key="${tag_word%%=*}"
|
||||||
|
local value="${tag_word#*=}"
|
||||||
|
|
||||||
|
if [[ "$key" == "mood" ]]; then
|
||||||
|
# Suggest only predefined mood values
|
||||||
|
compadd -- "${_fixed_moods[@]}"
|
||||||
|
else
|
||||||
|
# For other keys, do not suggest anything to prevent file completions
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Suggest tag keys
|
||||||
|
local keys=("mood" "genre" "rating" "custom1" "custom2")
|
||||||
|
compadd -- "${keys[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete for updating tags (key=value)
|
||||||
|
_mympc_update_tags() {
|
||||||
|
# Get the current word being completed
|
||||||
|
local tag_word="${words[CURRENT]}"
|
||||||
|
|
||||||
|
if [[ "$tag_word" == " " ]]; then
|
||||||
|
# Extract the key from 'key=value'
|
||||||
|
local key="${tag_word%%=*}"
|
||||||
|
local value="${tag_word#*=}"
|
||||||
|
|
||||||
|
if [[ "$key" == "mood" ]]; then
|
||||||
|
# Suggest only predefined mood values
|
||||||
|
compadd -- "${_fixed_moods[@]}"
|
||||||
|
else
|
||||||
|
# For other keys, do not suggest anything to prevent file completions
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Suggest existing tag keys from the current song
|
||||||
|
local song_uri
|
||||||
|
song_uri=$(mpc --format %file% current)
|
||||||
|
local -a keys
|
||||||
|
keys=($(mpc sticker "$song_uri" list 2>/dev/null | cut -d'=' -f1))
|
||||||
|
compadd -- "${keys[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete for deleting tags (only keys)
|
||||||
|
_mympc_delete_tags() {
|
||||||
|
local song_uri
|
||||||
|
song_uri=$(mpc --format %file% current)
|
||||||
|
local -a tags
|
||||||
|
tags=($(mpc sticker "$song_uri" list 2>/dev/null | cut -d'=' -f1))
|
||||||
|
compadd -- "${tags[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete for generating playlist by mood
|
||||||
|
_my_mpc_playlist_by_mood() {
|
||||||
|
# Use the predefined mood list for suggestions
|
||||||
|
_values "mood" "${_fixed_moods[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Register the autocompletion function with Zsh
|
||||||
|
compdef _mympc mympc
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user