====== Add played music to database ======
This script will write all the artists, tracks and albums played on Spotify to a MySQL database.
===== Database =====
{{:linux:ubuntu:pasted:20230118-151359.png?800}}
CREATE TABLE `album` (
`artist_id` smallint(5) NOT NULL DEFAULT '0',
`album_id` smallint(5) NOT NULL,
`album_name` char(128) DEFAULT NULL,
`album_cover` varchar(1000) DEFAULT NULL,
`album_type` varchar(128) DEFAULT NULL,
`album_releasedate` date DEFAULT NULL,
`album_tracknumber` smallint(5) DEFAULT NULL,
`album_spotifyurl` varchar(128) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `artist` (
`artist_id` smallint(5) NOT NULL,
`artist_name` char(128) DEFAULT NULL,
`artist_spotifyurl` varchar(128) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `connectalbumtrack` (
`album_id` smallint(10) NOT NULL,
`track_id` smallint(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `connectartisttrack` (
`artist_id` smallint(10) NOT NULL,
`track_id` smallint(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `played` (
`artist_id` smallint(5) NOT NULL DEFAULT '0',
`album_id` smallint(5) NOT NULL DEFAULT '0',
`track_id` smallint(5) NOT NULL DEFAULT '0',
`played` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `track` (
`artist_id` smallint(5) NOT NULL DEFAULT '0',
`album_id` smallint(5) NOT NULL DEFAULT '0',
`track_id` smallint(5) NOT NULL,
`track_name` char(255) DEFAULT NULL,
`track_popularity` int(20) DEFAULT NULL,
`track_tracknumber` smallint(5) DEFAULT NULL,
`track_previewurl` varchar(128) DEFAULT NULL,
`track_spotifyurl` varchar(128) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `album`
ADD PRIMARY KEY (`album_id`),
ADD KEY `album_id` (`album_id`),
ADD KEY `artist_id` (`artist_id`);
ALTER TABLE `artist`
ADD PRIMARY KEY (`artist_id`),
ADD UNIQUE KEY `artist_id_2` (`artist_id`),
ADD KEY `artist_id` (`artist_id`),
ADD KEY `artist_id_3` (`artist_id`);
ALTER TABLE `connectalbumtrack`
ADD KEY `album_id` (`album_id`),
ADD KEY `track_id` (`track_id`);
ALTER TABLE `connectartisttrack`
ADD KEY `artist_id` (`artist_id`),
ADD KEY `track_id` (`track_id`);
ALTER TABLE `played`
ADD KEY `artist_id` (`artist_id`),
ADD KEY `album_id` (`album_id`),
ADD KEY `track_id` (`track_id`);
ALTER TABLE `track`
ADD PRIMARY KEY (`track_id`),
ADD KEY `track_id` (`track_id`),
ADD KEY `artist_id` (`artist_id`),
ADD KEY `album_id` (`album_id`);
ALTER TABLE `album`
MODIFY `album_id` smallint(5) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=55;
ALTER TABLE `artist`
MODIFY `artist_id` smallint(5) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=71;
ALTER TABLE `track`
MODIFY `track_id` smallint(5) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=69;
ALTER TABLE `album`
ADD CONSTRAINT `album_ibfk_1` FOREIGN KEY (`artist_id`) REFERENCES `artist` (`artist_id`);
ALTER TABLE `connectalbumtrack`
ADD CONSTRAINT `connectalbumtrack_ibfk_1` FOREIGN KEY (`track_id`) REFERENCES `track` (`track_id`),
ADD CONSTRAINT `connectalbumtrack_ibfk_2` FOREIGN KEY (`album_id`) REFERENCES `album` (`album_id`);
ALTER TABLE `connectartisttrack`
ADD CONSTRAINT `connectartisttrack_ibfk_1` FOREIGN KEY (`artist_id`) REFERENCES `artist` (`artist_id`),
ADD CONSTRAINT `connectartisttrack_ibfk_2` FOREIGN KEY (`track_id`) REFERENCES `track` (`track_id`);
ALTER TABLE `played`
ADD CONSTRAINT `played_ibfk_1` FOREIGN KEY (`artist_id`) REFERENCES `artist` (`artist_id`),
ADD CONSTRAINT `played_ibfk_2` FOREIGN KEY (`album_id`) REFERENCES `album` (`album_id`),
ADD CONSTRAINT `played_ibfk_3` FOREIGN KEY (`track_id`) REFERENCES `track` (`track_id`);
ALTER TABLE `track`
ADD CONSTRAINT `track_ibfk_1` FOREIGN KEY (`artist_id`) REFERENCES `artist` (`artist_id`),
ADD CONSTRAINT `track_ibfk_2` FOREIGN KEY (`album_id`) REFERENCES `album` (`album_id`);
===== Script =====
==== Bashscript ====
#!/bin/bash
#----------VARS----------#
#Path to logfile
LOGPATH=/var/log/mysqlinsert_spotify.log
#Login for MYSQL
LOGIN="local"
#Database
DB=spotifymusic
TMPFILE=/tmp/spotifyaudio.json
WEBFILE=/var/www/mysite/spotifyaudio.php
WEBFILE2=/var/www/mysite/spotifyaudio2.php
ACCESSTOKENFILE="/spotify/token.json"
ACCESSTOKEN=`jq -r ".access_token" $ACCESSTOKENFILE`
BASICAUTH="yourAUTHkey"
REFRESH_TOKEN="yourREFRESHtoken"
#----------GET_CURRENT_TRACK_INFO----------#
GET_CURRENT_TRACK_INFO () {
OFFLINE=`cat $TMPFILE | jq -r '.is_playing'`
#define array length
ARTISTNUMBER=`cat $TMPFILE | jq '.item.artists | length'`
#artists to array
if [ -z "$ARTISTNUMBER" ]
then
ARTISTNUMBER="0"
fi
if [ "$ARTISTNUMBER" -gt "1" ];then
declare -ga ARTISTARRAY=()
for ((i=1; i<=$ARTISTNUMBER; i+=1)); do
j=$(($i-1))
ARTISTS=`cat $TMPFILE | jq -r ".item.artists[$j].name"`
ARTISTARRAY+=("$ARTISTS")
done
echo ${ARTISTARRAY[0]}
echo ${ARTISTARRAY[1]}
printf -v ARTISTARRAYOUTPUT '%s,' "${ARTISTARRAY[@]}"; echo "${ARTISTARRAYOUTPUT%,}" | sed 's/, */, /g' > /tmp/artists.txt
else
ARTIST=`cat $TMPFILE | jq -r '.item.artists[0].name'`
fi
#spotifyinfo to vars
export ARTISTSPOTIFYURL=`cat $TMPFILE | jq -r '.item.artists[0].external_urls.spotify'`
export TITLE=`cat $TMPFILE | jq -r '.item.name'`
export TITLENUMBER=`cat $TMPFILE | jq -r '.item.track_number'`
export TITLEPOPULARITY=`cat $TMPFILE | jq -r '.item.popularity'`
export TITLESPOTIFYURL=`cat $TMPFILE | jq -r '.item.external_urls.spotify'`
export TITLESPOTIFYPREVIEWURL=`cat $TMPFILE | jq -r '.item.preview_url'`
export ALBUM=`cat $TMPFILE | jq -r '.item.album.name'`
export ALBUMTYPE=`cat $TMPFILE | jq -r '.item.album.album_type'`
export ALBUMTRACKS=`cat $TMPFILE | jq -r '.item.album.total_tracks'`
export ALBUMSPOTIFYURL=`cat $TMPFILE | jq -r '.item.album.external_urls.spotify'`
export ALBUMRELEASEDATE=`cat $TMPFILE | jq -r '.item.album.release_date'`
export ALBUMIMG=`cat $TMPFILE | jq -r '.item.album.images[0].url'`
}
#----------GET_SPOTIFY_TRACK----------#
GET_SPOTIFY_TRACK () {
curl -X "GET" "https://api.spotify.com/v1/me/player/currently-playing" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer "$ACCESSTOKEN"" > $TMPFILE
}
#----------CHECK_TOKEN----------#
CHECK_TOKEN () {
grep -i '"status": 401,\|"status": 400,' $TMPFILE && return 0 || return 1
}
#----------REFRESH_TOKEN----------#
REFRESH_TOKEN () {
curl -H "Authorization: Basic $BASICAUTH" -d grant_type="refresh_token" -d refresh_token="$REFRESH_TOKEN" -d redirect_uri="http%3A%2F%2Flocalhost:4815%2Fcallback%2F" https://accounts.spotify.com/api/token > $ACCESSTOKENFILE
ACCESSTOKEN=`jq -r ".access_token" $ACCESSTOKENFILE`
}
#----------WRITE_TO_WEBSITE----------#
WRITE_TO_WEBSITE () {
echo "" > $WEBFILE
#sometimes $ARTISTS was empty, this is the workaround, might be fixed in the meantime
WHYUNOWORKIN=$(cat /tmp/artists.txt)
if [ -z "$OFFLINE" ]
then
OFFLINE="false"
fi
if [ "$OFFLINE" != "false" ]; then
echo "" >> $WEBFILE
echo "
" >> $WEBFILE
echo "
" >> $WEBFILE
echo "
" >> $WEBFILE
echo "
State:
" >> $WEBFILE
echo "
PLAYING
" >> $WEBFILE
echo "
" >> $WEBFILE
echo "
" >> $WEBFILE
echo "
" >> $WEBFILE
echo "
Artist:
" >> $WEBFILE
if [ -z "$ARTIST" ]; then
echo "
"$WHYUNOWORKIN"
" >> $WEBFILE
else
echo "
"$ARTIST"
" >> $WEBFILE
fi
echo "
" >> $WEBFILE
echo "
" >> $WEBFILE
echo "
" >> $WEBFILE
echo "
Title:
" >> $WEBFILE
echo "
"$TITLE"
" >> $WEBFILE
echo "
" >> $WEBFILE
echo "
" >> $WEBFILE
echo "
Album:
" >> $WEBFILE
echo "
"$ALBUM"
" >> $WEBFILE
echo "
" >> $WEBFILE
echo "
" >> $WEBFILE
echo "
" >> $WEBFILE
else
echo "" >> $WEBFILE
echo "
" >> $WEBFILE
echo "Iam not listening to music right now..." >> $WEBFILE
echo "
" >> $WEBFILE
fi
}
#----------WRITE_TO_MYSQL----------#
WRITE_TO_MYSQL () {
#wanted to use the comparison below but it didnt work. maybe someone knows how to fix it?
#HASH="$(cmp --silent $WEBFILE $WEBFILE2; echo $?)" # "$?" gives exit status for each comparison
#If a FILE is '-' or missing, read standard input. Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.
HASHONE=$(md5sum $WEBFILE | cut -d " " -f1)
HASHTWO=$(md5sum $WEBFILE2 | cut -d " " -f1)
if [ "$HASHONE" != "$HASHTWO" ]
then # if status is equal to 1, then execute code
DBTRACK=$(mysql --login-path=$LOGIN -D $DB -se "SELECT track_id FROM track WHERE track_name = '$TITLE'")
DBALBUM=$(mysql --login-path=$LOGIN -D $DB -se "SELECT album_id FROM album WHERE album_name = '$ALBUM'")
if [ "$ARTISTNUMBER" -gt "1" ];then
for ((i = 0; i < ${#ARTISTARRAY[*]}; i++))
do
DBARTIST=$(mysql --login-path=$LOGIN -D $DB -se "SELECT artist_id FROM artist WHERE artist_name = '${ARTISTARRAY[$i]}'")
if [ -z "$DBARTIST" ]
then
mysql --login-path=$LOGIN -D $DB << EOFMYSQL
INSERT INTO artist (artist_name,artist_spotifyurl)
VALUES ('${ARTISTARRAY[$i]}','$ARTISTSPOTIFYURL');
EOFMYSQL
fi
done
else
echo "artist"
echo $ARTIST
DBARTIST=$(mysql --login-path=$LOGIN -D $DB -se "SELECT artist_id FROM artist WHERE artist_name = '$ARTIST'")
if [ -z "$DBARTIST" ]
then
mysql --login-path=$LOGIN -D $DB << EOFMYSQL
INSERT INTO artist (artist_name,artist_spotifyurl)
VALUES ('$ARTIST','$ARTISTSPOTIFYURL');
EOFMYSQL
fi
fi
if [ "$ARTISTNUMBER" -gt "1" ];then
DBARTISTNEW=$(mysql --login-path=$LOGIN -D $DB -se "SELECT artist_id FROM artist WHERE artist_name = '${ARTISTARRAY[0]}'")
else
DBARTISTNEW=$(mysql --login-path=$LOGIN -D $DB -se "SELECT artist_id FROM artist WHERE artist_name = '$ARTIST'")
fi
if [ -z "$DBALBUM" ]
then
if [ "$ARTISTNUMBER" -gt "1" ];then
mysql --login-path=$LOGIN -D $DB << EOFMYSQL
INSERT INTO album (album_name,album_cover,artist_id,album_type,album_releasedate,album_tracknumber,album_spotifyurl)
VALUES ('$ALBUM','$ALBUMIMG','$DBARTISTNEW','$ALBUMTYPE','$ALBUMRELEASEDATE','$ALBUMTRACKS','$ALBUMSPOTIFYURL');
EOFMYSQL
else
mysql --login-path=$LOGIN -D $DB << EOFMYSQL
INSERT INTO album (album_name,album_cover,artist_id,album_type,album_releasedate,album_tracknumber,album_spotifyurl)
VALUES ('$ALBUM','$ALBUMIMG','$DBARTISTNEW','$ALBUMTYPE','$ALBUMRELEASEDATE','$ALBUMTRACKS','$ALBUMSPOTIFYURL');
EOFMYSQL
fi
fi
DBALBUMNEW=$(mysql --login-path=$LOGIN -D $DB -se "SELECT album_id FROM album WHERE album_name = '$ALBUM'")
if [ -z "$DBTRACK" ]
then
if [ "$ARTISTNUMBER" -gt "1" ];then
mysql --login-path=$LOGIN -D $DB << EOFMYSQL
INSERT INTO track (track_name,album_id,artist_id,track_tracknumber,track_popularity,track_previewurl,track_spotifyurl)
VALUES ('$TITLE','$DBALBUMNEW','$DBARTISTNEW','$TITLENUMBER','$TITLEPOPULARITY','$TITLESPOTIFYPREVIEWURL','$TITLESPOTIFYURL');
EOFMYSQL
else
mysql --login-path=$LOGIN -D $DB << EOFMYSQL
INSERT INTO track (track_name,album_id,artist_id,track_tracknumber,track_popularity,track_previewurl,track_spotifyurl)
VALUES ('$TITLE',$DBALBUMNEW,'$DBARTISTNEW','$TITLENUMBER','$TITLEPOPULARITY','$TITLESPOTIFYPREVIEWURL','$TITLESPOTIFYURL');
EOFMYSQL
fi
fi
DBTRACKNEW=$(mysql --login-path=$LOGIN -D $DB -se "SELECT track_id FROM track WHERE track_name = '$TITLE'")
DBALBUMTRACK=$(mysql --login-path=$LOGIN -D $DB -se "SELECT a.album_name, c.track_name FROM album a, connectalbumtrack b, track c WHERE b.album_id = '$DBALBUMNEW' AND b.track_id = '$DBTRACKNEW'")
#connectartisttrack
if [ "$ARTISTNUMBER" -gt "1" ]
then
for ((i = 0; i < ${#ARTISTARRAY[*]}; i++))
do
DBARTISTNEW=$(mysql --login-path=$LOGIN -D $DB -se "SELECT artist_id FROM artist WHERE artist_name = '${ARTISTARRAY[$i]}'")
DBARTISTTRACK=$(mysql --login-path=$LOGIN -D $DB -se "SELECT a.artist_name, c.track_name FROM artist a, connectartisttrack b, track c WHERE b.artist_id = '$DBARTISTNEW' AND b.track_id = '$DBTRACKNEW'")
if [ -z "$DBARTISTTRACK" ]
then
mysql --login-path=$LOGIN -D $DB << EOFMYSQL
INSERT INTO connectartisttrack (artist_id,track_id)
VALUES ('$DBARTISTNEW','$DBTRACKNEW');
EOFMYSQL
fi
done
else
DBARTISTNEW=$(mysql --login-path=$LOGIN -D $DB -se "SELECT artist_id FROM artist WHERE artist_name = '$ARTIST'")
DBARTISTTRACK=$(mysql --login-path=$LOGIN -D $DB -se "SELECT a.artist_name, c.track_name FROM artist a, connectartisttrack b, track c WHERE b.artist_id = '$DBARTISTNEW' AND b.track_id = '$DBTRACKNEW'")
if [ -z "$DBARTISTTRACK" ]
then
mysql --login-path=$LOGIN -D $DB << EOFMYSQL
INSERT INTO connectartisttrack (artist_id,track_id)
VALUES ('$DBARTISTNEW','$DBTRACKNEW');
EOFMYSQL
fi
fi
#connectalbumtrack
if [ -z "$DBALBUMTRACK" ]
then
mysql --login-path=$LOGIN -D $DB << EOFMYSQL
INSERT INTO connectalbumtrack (album_id,track_id)
VALUES ('$DBALBUMNEW','$DBTRACKNEW');
EOFMYSQL
fi
#played is not yet fixed for multiple artists and just uses the first one
if [ "$ARTISTNUMBER" -gt "1" ];then
mysql --login-path=$LOGIN -D $DB << EOFMYSQL
INSERT INTO played (artist_id,track_id,album_id)
VALUES ('$DBARTISTNEW','$DBTRACKNEW','$DBALBUMNEW');
EOFMYSQL
else
mysql --login-path=$LOGIN -D $DB << EOFMYSQL
INSERT INTO played (artist_id,track_id,album_id)
VALUES ('$DBARTISTNEW','$DBTRACKNEW','$DBALBUMNEW');
EOFMYSQL
fi
#copy webfile to webfile2 for comparison in the next run
cp -a $WEBFILE $WEBFILE2
fi
}
#----------MAIN----------#
GET_SPOTIFY_TRACK
CHECK_TOKEN
LASTSTATUS=`echo $?`
if [ "$LASTSTATUS" -eq 0 ];then
REFRESH_TOKEN
GET_SPOTIFY_TRACK
fi
GET_CURRENT_TRACK_INFO
WRITE_TO_WEBSITE
WRITE_TO_MYSQL
==== Automation ====
The bashscript can be automated via crontab (example runs every 2 minutes).
*/2 * * * * /spotify/copySpotifyinSQL.sh >/dev/null 2>&1