Commit Diff


commit - /dev/null
commit + 9733f193718b3d5d83f13fda130a7508ac906ded
blob - /dev/null
blob + ee7d6a54e91479b8b51312c8f603a2c10d53d1ee (mode 644)
--- /dev/null
+++ 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.

+

blob - /dev/null
blob + 807f8581016d5164f309fbc6b0cd37a41c38b660 (mode 644)
--- /dev/null
+++ 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!
blob - /dev/null
blob + ce41fa3ea55cc49d5f7ce74c95fb0678d9a5fd72 (mode 755)
--- /dev/null
+++ 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
blob - /dev/null
blob + 343a825f4159610316e9e5c0775f74ff39657987 (mode 755)
--- /dev/null
+++ 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"