#!/bin/sh
#
# $Id: karma.in,v 1.14 2024-12-23 19:08:21+05:30 Cprogrammer Exp mbhangui $
#

get_mpd_conf_value()
{
  grep "^$1" /etc/mpd.conf|awk '{print $2}' | \
  sed -e 's{"{{g'
}

usage()
{
if [ -f /usr/bin/less ] ; then
	MORE=/usr/bin/less
else
	MORE=/usr/bin/more
fi
echo "Press ENTER for options, Cntrl C to quit" 1>&2
read key
$MORE 1>&2 <<EOF
Usage: karma [OPTION]

Known values for OPTION are:

--value=karma
  Set karma to karma. If not set, karma is set as 50

-u path
--uri=path
  Finds song with uri matching path

-i songID
--id=songID
  Finds song with id matching songID

-k
--karma
  Find songs with karma as per expression. e.g.
  --karma <50  means songs with karma less than 50
  --karma <=50 means songs with karma less than or equal to 50
  --karma =50  means songs with karma equal to 50
  --karma >=50 means songs with karma greater than or equal to 50
  --karma >50  means songs with karma greater than 50

-p
--playcount=exp
  Find songs with playcounts as per expression. e.g.
  --playcount <5  means songs with play counts less than 5
  --playcount <=5 means songs with play counts less than or equal to 5
  --playcount =5  means songs with play counts equal to 5
  --playcount >=5 means songs with play counts greater than or equal to 5
  --playcount >5  means songs with play counts greater than 5

-r
--rating
  Find songs with karma as per expression. e.g.
  --rating <6  means gons with ratings less than 6
  --rating <=6 means gons with ratings less than or equal to 6
  --rating =6  means gons with ratings equal to 6
  --rating >=6 means gons with ratings greater than or equal to 6
  --rating >6  means gons with ratings greater than 6
 
-a Artist
--artist=Artist
  Find songs with Artist exactly matching 'Artist'

--artistany=keyword
  Find songs with Artist having 'keyword' anywhere in the Artist field

--query
  Display SQL query, results and exit

-h
--help
  display this help and exit

EOF
exit $1
}

process_cmdline()
{
SYSTEM=$(uname -s)
case "$OS" in
	Darwin)
	if [ -x /opt/local/bin/getopt ] ; then
		getopt="/opt/local/bin/getopt"
	elif [ -x /usr/local/bin/getopt ] ; then
		getopt="/usr/local/bin/getopt"
	else
		getopt=getopt
	fi
	;;
	*)
	getopt=getopt
	;;
esac
OPTS=`$getopt -o v:u:i:k:a:p:r:h --long value:,uri:,id:,karma:,artist:,artistany,playcount:,rating:,query,love,unlove,help -- "$@"`
if [ $? -ne 0 ] ; then
	usage 1
fi
eval set -- "$OPTS"
#echo "$@"
while true; do
	case "$1" in
		-v|--value)
			karma_val=$2 ; shift 2 ;;
		-u|--uri)
			song_uri=$2 ; shift 2 ;;
		-i|--id)
			song_id=$2 ; shift 2 ;;
		-k|--karma)
			if [ "${2:0:1}" = ">" -o "${2:0:1}" = "<" -o "${2:0:1}" = "=" ] ; then
				karma="karma$2" ; shift 2 ;
			else
				karma="karma=$2" ; shift 2 ;
			fi ;;
		-a|--artist)
			exact=1; artist=${2/ /_}; shift 2;;
		--artistany)
			exact=0; artist=${2/ /_}; shift 2;;
		-p|--playcount)
			if [ "${2:0:1}" = ">" -o "${2:0:1}" = "<" -o "${2:0:1}" = "=" ] ; then
				play_counts="play_count$2" ; shift 2 ;
			else
				play_counts="play_count=$2" ; shift 2 ;
			fi ;;
		-r|--rating)
			if [ "${2:0:1}" = ">" -o "${2:0:1}" = "<" -o "${2:0:1}" = "=" ] ; then
				rating="rating$2" ; shift 2 ;
			else
				rating="rating=$2" ; shift 2 ;
			fi ;;
		--query)
			do_update=0; shift 1;;
		--love)
			scrobble_love=1; shift 1;;
		--unlove)
			scrobble_unlove=1; shift 1;;
		-h|--help)
			usage 0 ;;
		--) shift; break;;
		*)
			echo "invalid option [$1]" 1>&2; usage 1; break;;
	esac
done
}

song_id=""
karma=""
artist=""
rating=""
play_counts=""
do_update=1
scrobble_love=0
scrobble_unlove=0
process_cmdline "$@"

if [ $# -eq 0 ] ; then
	do_update=0
	song_uri=$(mpc current -f %file% | sed -e "s{'{''{g")
	if [ -z "$song_uri" ] ; then
		echo "No song playing and no options given" 1>&2
		usage 1
	fi
fi

music_dir=`get_mpd_conf_value music_directory`
if [ $? -ne 0 ] ; then
  echo "could not get music directory from mpd.conf" 1>&2
  exit 1
fi
sticker_file=`get_mpd_conf_value sticker_file`
if [ $? -ne 0 ] ; then
  echo "could not get sticker database from mpd.conf" 1>&2
  exit 1
fi
stats_dir=$(dirname $sticker_file)
stats_file=$stats_dir/stats.db
if [ -z "$stats_file" ] ; then
  echo "Unable to find value of stats.db location" 1>&2
  exit 1
fi
if [ ! -f "$stats_file" ] ; then
  echo "$stats_file: No such file or directory" 1>&2
  exit 1
fi

sql_query_select="SELECT karma, id, uri FROM song "
sql_query_update="UPDATE song set karma=$karma_val "
first_condition=""

if [ $scrobble_love -eq 1 -o $scrobble_unlove -eq 1 ] ; then
	song_uri=$(mpc current -f %file% | sed -e "s{'{''{g")
	if [ -z "$song_uri" ] ; then
		echo "No song playing and no options given" 1>&2
		exit 1
	fi
	sql_query_s="SELECT title, artist, album FROM song WHERE uri='${song_uri}'"
	sqlite3 -noheader -batch $stats_file "$sql_query_s" | while IFS='|' read track artist album
	do
		tty -s
		ret=$?
		if [ $scrobble_love -eq 1 ] ; then
			echo "marking scrobble as loved on lastfm"
			if [ $ret -eq 0 ] ; then
				lastfm-scrobbler --love --artist="$artist" --track="$track" --album="$album"
			else
				lastfm-scrobbler --love --artist="$artist" --track="$track" --album="$album" > /dev/null
			fi
			echo "marking scrobble as loved on librefm"
			if [ $ret -eq 0 ] ; then
				librefm-scrobbler --love --artist="$artist" --track="$track" --album="$album"
			else
				librefm-scrobbler --love --artist="$artist" --track="$track" --album="$album" > /dev/null
			fi
		else
			echo "marking scrobble as unloved on lastfm"
			if [ $ret -eq 0 ] ; then
				lastfm-scrobbler --unlove --artist="$artist" --track="$track" --album="$album"
			else
				lastfm-scrobbler --unlove --artist="$artist" --track="$track" --album="$album" > /dev/null
			fi
			echo "marking scrobble as unloved on librefm"
			if [ $ret -eq 0 ] ; then
				librefm-scrobbler --unlove --artist="$artist" --track="$track" --album="$album"
			else
				librefm-scrobbler --unlove --artist="$artist" --track="$track" --album="$album" > /dev/null
			fi
		fi
	done
	exit 0
fi
if [ -z "$song_uri" -a -z "$song_id" -a -z "$artist" -a -z "$rating" -a -z "$play_counts" -a -z "$karma" ] ; then
	song_uri=$(mpc current -f %file% | sed -e "s{'{''{g")
	if [ -z "$song_uri" ] ; then
		echo "No song playing and no options given" 1>&2
		usage 1
	fi
fi

if [ -n "$song_uri" ] ; then
	if [ "$song_uri" = "current" ] ; then
		song_uri=$(mpc current -f %file% | sed -e "s{'{''{g")
		if [ -z "$song_uri" ] ; then
			echo "No song playing" 1>&2
  			exit 1
		fi
	fi
	if [ -z "$first_condition" ] ; then
		sql_query_s="$sql_query_select WHERE"
		sql_query_u="$sql_query_update WHERE"
		first_condition=1
	else
		sql_query_s="$sql_query_s AND"
		sql_query_u="$sql_query_u AND"
	fi
	sql_query_s="$sql_query_s uri='${song_uri}'"
	sql_query_u="$sql_query_u uri='${song_uri}'"
fi
if [ -n "$song_id" ] ; then
	if [ -z "$first_condition" ] ; then
		sql_query_s="$sql_query_select WHERE"
		sql_query_u="$sql_query_update WHERE"
		first_condition=1
	else
		sql_query_s="$sql_query_s AND"
		sql_query_u="$sql_query_u AND"
	fi
	sql_query_s="$sql_query_s id='$song_id'"
	sql_query_u="$sql_query_u id='$song_id'"
fi
if [ -n "$artist" ] ; then
	if [ -z "$first_condition" ] ; then
		sql_query_s="$sql_query_select WHERE"
		sql_query_u="$sql_query_update WHERE"
		first_condition=1
	elif [ -n "$first_condition" ] ; then
		sql_query_s="$sql_query_s AND"
		sql_query_u="$sql_query_u AND"
	fi
	f=`echo $artist|sed "s/_/ /g"`
	if [ $exact -eq 1 ] ; then
		sql_query_s="$sql_query_s artist='$f'"
		sql_query_u="$sql_query_u artist='$f'"
	else
		sql_query_s="$sql_query_s artist like '%$f%'"
		sql_query_u="$sql_query_u artist like '%$f%'"
	fi
fi
if [ -n "$rating" ] ; then
	if [ -z "$first_condition" ] ; then
		sql_query_s="$sql_query_select WHERE"
		sql_query_u="$sql_query_update WHERE"
		first_condition=1
	elif [ -n "$first_condition" ] ; then
		sql_query_s="$sql_query_s AND"
		sql_query_u="$sql_query_u AND"
	fi
	sql_query_s="$sql_query_s rating=$rating"
	sql_query_u="$sql_query_u rating=$rating"
fi
if [ -n "$play_counts" ] ; then
	if [ -z "$first_condition" ] ; then
		sql_query_s="$sql_query_select WHERE"
		sql_query_u="$sql_query_update WHERE"
		first_condition=1
	elif [ -n "$first_condition" ] ; then
		sql_query_s="$sql_query_s AND"
		sql_query_u="$sql_query_u AND"
	fi
	sql_query_s="$sql_query_s play_count=$play_counts"
	sql_query_u="$sql_query_u play_count=$play_counts"
fi
if [ -n "$karma" ] ; then
	if [ -z "$first_condition" ] ; then
		sql_query_s="$sql_query_select WHERE"
		sql_query_u="$sql_query_update WHERE"
		first_condition=1
	elif [ -n "$first_condition" ] ; then
		sql_query_s="$sql_query_s AND"
		sql_query_u="$sql_query_u AND"
	fi
	sql_query_s="$sql_query_s karma=$karma"
	sql_query_u="$sql_query_u karma=$karma"
fi
if [ $do_update -eq 1 -a -n "$karma_val" ] ; then
	/usr/bin/sqlite3 -column -header "$stats_file" "$sql_query_s";
	/usr/bin/sqlite3 "$stats_file" "$sql_query_u";
	/usr/bin/sqlite3 -column -noheader "$stats_file" "$sql_query_s";
else
	/usr/bin/sqlite3 -column -header "$stats_file" "$sql_query_s";
fi
exit 0
#
# $Log: karma.in,v $
# Revision 1.14  2024-12-23 19:08:21+05:30  Cprogrammer
# fix for darwin
#
# Revision 1.13  2024-04-09 23:24:45+05:30  Cprogrammer
# display scrobble command if running with a tty
#
# Revision 1.12  2024-04-08 22:49:51+05:30  Cprogrammer
# added unlove function
#
# Revision 1.11  2023-07-05 22:00:13+05:30  Cprogrammer
# added --love option to mark scrobble as loved
#
# Revision 1.10  2022-09-26 19:07:10+05:30  Cprogrammer
# exit if getopt returns error
#
# Revision 1.9  2022-05-10 21:43:20+05:30  Cprogrammer
# merged modifictions by https://github.com/Plexvol (use getopt)
#
# Revision 1.8  2021-10-15 20:02:56+05:30  Cprogrammer
# set song_uri to current playing song if no options are provided
#
# Revision 1.7  2021-10-15 18:31:39+05:30  Cprogrammer
# fixed update not working
#
# Revision 1.6  2021-10-14 22:39:14+05:30  Cprogrammer
# fixed typo
#
# Revision 1.5  2021-10-11 00:32:37+05:30  Cprogrammer
# fixed sql statement
#
# Revision 1.4  2021-09-30 20:30:25+05:30  Cprogrammer
# use -noheader option to prevent .sqlitrc settings messing with results
#
# Revision 1.3  2021-09-30 11:39:51+05:30  Cprogrammer
# display karma for current playing song when no options are provided
#
# Revision 1.2  2021-09-09 20:41:02+05:30  Cprogrammer
# added missing help display for --value
#
# Revision 1.1  2021-04-24 11:46:17+05:30  Cprogrammer
# Initial revision
