summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYING14
-rw-r--r--README.md3
-rwxr-xr-xmpc-notify126
-rwxr-xr-xnotify-replace37
4 files changed, 180 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..ee7d6a5
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,14 @@
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
+
+ Everyone is permitted to copy and distribute verbatim or modified
+ copies of this license document, and changing it is allowed as long
+ as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..807f858
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+Some useful scripts I wrote. I used some code lines from the internet as a
+base or inspiration; I add links to my sources when approprite.
+Enjoy!
diff --git a/mpc-notify b/mpc-notify
new file mode 100755
index 0000000..ce41fa3
--- /dev/null
+++ b/mpc-notify
@@ -0,0 +1,126 @@
+#!/bin/dash
+# Based on:
+# https://wiki.archlinux.org/title/Ncmpcpp#With_album_art
+
+# Sends notification with album cover art using mpc, ffmpeg, notify-send,
+# and my other script, notify-replace.
+# For notification on song change:
+# Assign execute_on_song_change to this script in ncmpcpp's config file.
+# For notification on media keys:
+# Bind media key to a call to mpc with the approprite command.
+
+# FEATURE: make width and height configurable through flags
+preview_width=64
+preview_height=64
+default_song_icon="media-playback-start"
+xdg_config_home="${XDG_CONFIG_HOME:-$HOME/.config}"
+mpc_config_dir="$xdg_config_home/mpc"
+[ -d "$mpc_config_dir" ] || mkdir -p "$mpc_config_dir"
+
+# issue an mpc command based on arguments and assemble notification message
+use_preview=0
+case "$1" in
+ "")
+ # use defaults
+ song_head="Now Playing"
+ use_preview=1
+ ;;
+ "toggle")
+ mpc -q toggle
+ state="$(mpc status %state%)"
+ if [ "$state" = "playing" ]; then
+ song_head="Now Playing"
+ use_preview=1
+ elif [ "$state" = "paused" ]; then
+ song_head="Paused"
+ song_icon="media-playback-pause"
+ fi
+ ;;
+ "shuffle")
+ mpc -q shuffle
+ song_head="Shuffled Playlist"
+ song_icon="media-playlist-shuffle"
+ ;;
+ "single")
+ mpc -q single
+ state="$(mpc status %single%)"
+ if [ "$state" = "on" ]; then
+ song_head="Single Mode: On"
+ elif [ "$state" = "once" ]; then
+ song_head="Single Mode: Once"
+ elif [ "$state" = "off" ]; then
+ song_head="Single Mode: Off"
+ fi
+ song_icon="multimedia-player"
+ ;;
+ "random")
+ mpc -q random
+ state="$(mpc status %random%)"
+ if [ "$state" = "on" ]; then
+ song_head="Random Mode: On"
+ elif [ "$state" = "off" ]; then
+ song_head="Random Mode: Off"
+ fi
+ song_icon="media-eject"
+ ;;
+ "repeat")
+ mpc -q repeat
+ state="$(mpc status %repeat%)"
+ if [ "$state" = "on" ]; then
+ song_head="Repeat Mode: On"
+ elif [ "$state" = "off" ]; then
+ song_head="Repeat Mode: Off"
+ fi
+ song_icon="media-playlist-repeat"
+ ;;
+ *)
+ mpc -q "$1"
+ # Don't notify if mpc changed song because ncmpcpp would notify on
+ # song change.
+ [ "$1" = "next" ] || [ "$1" = "prev" ] && exit
+ ;;
+esac
+song_body="$(mpc --format '[%title%[ \n%artist% - %album%]]|[%file%]' current)"
+
+# use album preview for song icon
+if [ "$use_preview" -eq 1 ]; then
+ preview_dir="$mpc_config_dir/previews"
+ [ -d "$preview_dir" ] || mkdir -p "$preview_dir"
+ music_dir="$(xdg-user-dir MUSIC)"
+
+ # get preview filename
+ song_filename="$(mpc --format "$music_dir"/%file% current)"
+ song_album="$(mpc --format %album% current)"
+ if [ -z "$song_album" ]; then
+ # fallback to default for empty album name
+ song_icon="$default_song_icon"
+ else
+ preview_path="$preview_dir/$(echo "$song_album" | base64).png"
+ if [ -f "$preview_path" ]; then
+ # use cached preview
+ song_icon="$preview_path"
+ elif ffmpeg -y -i "$song_filename" -an -vf \
+ scale="${preview_width}:${preview_height}" \
+ "$preview_path" >/dev/null 2>&1;
+ then
+ # or use generated preview
+ song_icon="$preview_path"
+ else
+ song_dirname=$(dirname "$song_filename")
+ art_filename="$(find "$song_dirname" -type f |
+ grep -Esm 1 '.*\.(jpg|png)')"
+ if [ $? -eq 0 ]; then
+ # or use scaled cover art from directory
+ ffmpeg -y -i "$art_filename" -an -vf \
+ scale="${preview_width}:${preview_height}" \
+ "$preview_path" >/dev/null 2>&1;
+ song_icon="$preview_path"
+ else
+ # or fallback to default icon
+ song_icon="$default_song_icon"
+ fi
+ fi
+ fi
+fi
+
+notify-replace 'mpc-notify' "$song_head" "$song_body" -i "$song_icon" -u low
diff --git a/notify-replace b/notify-replace
new file mode 100755
index 0000000..343a825
--- /dev/null
+++ b/notify-replace
@@ -0,0 +1,37 @@
+#!/biin/dash -e
+# Sends, remembers, and replaces notifications based on program name that's
+# passed as first argument to script.
+# Non-POSIX features used: flock(1)
+# TODO: consider replacing flock(1) with a POSIX-complaint alternative
+
+xdg_config_home="${XDG_CONFIG_HOME:-$HOME/.config}"
+config_dir="$xdg_config_home/notify-replace"
+[ -d "$config_dir" ] || mkdir -p "$config_dir"
+
+if [ -z "$1" ]; then
+ # TODO: check if there's a better way to acquire name of currently
+ # executing script
+ # TODO: get rid of subshell
+ program=$(basename $0)
+ # TODO: shorten line
+ echo "$program: Need to provide notification id filename as first argument" 1>&2
+ exit 1
+fi
+lockdir="$config_dir/notify-replace.lock"
+notification_file="$config_dir/$1"
+shift
+
+# Exit if lock is in use. A lock is used to prevent multiple invocations
+# of script from replacing notification id at the same time
+exec 9>"$lockdir"
+flock -n 9 || exit 1
+
+if [ -s "$notification_file" ]; then
+ # replace previous notification
+ nid="$(notify-send -pr "$(cat "$notification_file")" "$@")"
+else
+ # send new notification
+ nid="$(notify-send -p "$@")"
+fi
+# Remember ID of sent notification.
+printf '%s' "$nid" >"$notification_file"