Skip to content

Instantly share code, notes, and snippets.

@bonelifer
Forked from kostix/mpc.sh
Last active January 26, 2025 05:04
Show Gist options
  • Save bonelifer/116a6b0b2bdbdd25f28dbf0ae90050ba to your computer and use it in GitHub Desktop.
Save bonelifer/116a6b0b2bdbdd25f28dbf0ae90050ba to your computer and use it in GitHub Desktop.
mpc wrapper with a bit of interactivity
#!/bin/sh
# This script interacts with the `mpc` (Music Player Client) to manage playlists in MPD (Music Player Daemon).
# It allows the user to perform operations such as:
# - Viewing the current playlist with enumerated items.
# - Selecting, loading, or replacing playlists interactively.
# - Clearing the current playlist and loading a new one.
# Usage:
# - Run the script with no arguments to execute `mpc` commands.
# - Use specific arguments like 'playlist', 'iload', or 'replace' to invoke specialized functions.
# Enable exit on errors and on using unset variables
set -e -u
# Find the path to the `mpc` command using `which`
mpc=$(which mpc)
# If `mpc` is not found, exit the script with an error message
if [ -z "$mpc" ]; then
echo "Error: mpc not found. Please install it and try again."
exit 1
fi
# If no arguments are passed to the script, just execute the mpc command with the given arguments.
if [ $# -lt 1 ]; then
"$mpc" "$@" # Executes the mpc command with the passed arguments
exit $? # Exit with the status code of the mpc command
fi
# Function to select a playlist interactively with fzf (fuzzy finder)
select_playlist() {
# If no search terms are provided, simply list the playlists and let the user choose.
if [ $# -eq 0 ]; then
"$mpc" lsplaylists | fzf # Lists playlists and lets the user pick with fzf
else
# If search terms are provided, filter the playlists based on the search terms
terms="$@" # Capture the passed search terms
"$mpc" lsplaylists | fzf -q "$terms" # Filter playlists using fzf
fi
}
# Function to list the current playlist with enumerated items
enumerated_playlist() {
# Get the playlist from mpc and enumerate each item
"$mpc" playlist | { # Start a block to process the output of `mpc playlist`
i=1 # Initialize the counter for the enumeration
# Read each line (song) from the playlist
while read line; do
# Print the index and the song name (line)
printf "%d\t%s\n" $i "$line"
i=$((i+1)) # Increment the index for the next song
done
}
}
# Case statement to handle different command-line arguments
case "$1" in
# If the first argument is 'playlist', call the enumerated_playlist function
playlist)
enumerated_playlist # List the playlist with enumeration
;;
# If the first argument is 'iload', load a selected playlist interactively
iload)
shift # Remove the 'iload' argument and shift the rest
# Use the select_playlist function to select a playlist
playlist=$(select_playlist "$@") || exit 0 # If selection fails, exit the script
# If no playlist was selected (empty string), exit with code 0
test -z "$playlist" || exit 0
"$mpc" load "$playlist" # Load the selected playlist into mpc
;;
# If the first argument is 'ireplace' or 'irep', replace the current playlist with a new one interactively
ireplace|irep)
shift # Remove the 'ireplace' or 'irep' argument
# Select a playlist to replace the current one
playlist=$(select_playlist "$@") || exit 0 # Exit if no playlist is selected
# If no playlist was selected, exit with code 0
test -z "$playlist" || exit 0
"$mpc" clear # Clear the current playlist
"$mpc" load "$playlist" # Load the new playlist
"$mpc" play 1 # Start playing the first song in the new playlist
;;
# If the first argument is 'replace' or 'reload', clear the current playlist and load a new one
replace|reload)
shift # Remove the 'replace' or 'reload' argument
"$mpc" clear && "$mpc" load "$@" # Clear current playlist and load the new one
;;
# Default case: If no specific case matches, run mpc with the provided arguments
*)
"$mpc" "$@" # Execute mpc with the given arguments
;;
esac
@bonelifer
Copy link
Author

Here’s a detailed breakdown of the improvements made to the original script{done using chatGPT}:

1. Dynamic Detection of mpc Path

  • Original: The script had a hard-coded path for mpc (/usr/bin/mpc).
  • Improvement: The path to mpc is now dynamically determined using which mpc. This allows the script to find mpc regardless of where it's installed on the system.
    mpc=$(which mpc)
  • Reason: This improves flexibility, ensuring the script works even if mpc is installed in a non-standard location.

2. Error Handling for Missing mpc Command

  • Original: There was no check to ensure that mpc was available.
  • Improvement: Added a check to ensure mpc is found. If mpc is not available, the script prints an error message and exits.
    if [ -z "$mpc" ]; then
        echo "Error: mpc not found. Please install it and try again."
        exit 1
    fi
  • Reason: This prevents the script from running into errors if mpc isn't installed or not available in the PATH. It provides a clear error message to guide the user.

3. Improved Readability of mpc Path Handling

  • Original: The mpc path was hardcoded into the script.
  • Improvement: Replaced the hardcoded mpc=/usr/bin/mpc with a more flexible approach using which.
  • Reason: This enhances the script's portability and ease of maintenance, as it automatically detects where mpc is installed.

4. Clarified Comments

  • Original: The script had some comments, but they were sparse and not as detailed.
  • Improvement: Added comprehensive header and inline comments to explain the purpose of each section and key commands.
    • Header comments at the top explain the overall functionality of the script.
    • Inline comments describe specific logic, such as what each block or command does.
  • Reason: This improves the readability and maintainability of the script, making it easier for others (or yourself) to understand the logic in the future.

5. General Code Structure

  • Original: The original structure was mostly fine, but there were minor improvements made to consistency.
  • Improvement: Cleaned up function names (e.g., select_playlist() for clarity) and ensured all sections of the code were properly aligned and structured.
    • The select_playlist function is used for playlist selection, with a clearer name.
  • Reason: Better naming and structure improve the script's clarity and maintainability.

6. No Functional Logic Change

  • The logic of how the script works (selecting playlists, replacing playlists, loading them, etc.) remains the same. The improvements are focused on robustness, flexibility, and readability rather than altering functionality.

Summary of Improvements:

  • Dynamic mpc path detection: Ensures flexibility in locating mpc.
  • Error handling: Provides user feedback if mpc is not found.
  • Improved readability: More detailed comments and clearer structure for better understanding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment