Last active
September 16, 2021 00:48
-
-
Save gwillem/c3b33a148a0bcc93b3ffb03c9778adfb to your computer and use it in GitHub Desktop.
Ubuntu: add current Spotify song to favorites (playlist)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
[email protected] | |
Read current playing track from D-BUS and add it to my favorites | |
playlist. Any previous instances of the same track on the playlist are removed. | |
I have mapped this script to the XF86Favorite key of my Microsoft Natural Keyboard. | |
Requires: | |
- Spotipy @ https://github.com/plamere/spotipy: sudo pip3 install spotipy | |
- D-BUS & notify-send (default on (X)Ubuntu 16.04) | |
""" | |
from pprint import pprint | |
import sys | |
import os | |
import subprocess | |
import shlex | |
import spotipy | |
import spotipy.util as util | |
import re | |
# authorized met mijn account | |
USER = 'yourusername' | |
TOKEN = authorize_with_spotify() | |
PLAYLIST = 'spotify:user:<yourusername>:playlist:<yourfavoritesplaylistid>' | |
api = spotipy.Spotify(auth=TOKEN) | |
def authorize_with_spotify(): | |
# only need to run this once | |
# returns: token | |
os.environ['SPOTIPY_CLIENT_ID'] = 'xxx' | |
os.environ['SPOTIPY_CLIENT_SECRET'] = 'xxx' | |
os.environ['SPOTIPY_REDIRECT_URI'] = 'http://httpbin.org/get' | |
# https://developer.spotify.com/web-api/using-scopes/ | |
scopes = 'user-library-read user-library-modify playlist-modify-private playlist-read-private playlist-modify-public playlist-read-collaborative' | |
token = util.prompt_for_user_token('willemdg', scopes) | |
return token | |
def get_current_track_and_name(): | |
cmd = "dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata'" | |
metadata = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT).decode() | |
# normalize whitespace to make next regexes easier to read | |
metadata = re.sub('\s+', ' ', metadata, flags=re.MULTILINE) | |
track_id = re.search('string "mpris:trackid" variant string "(.+?)"', metadata).group(1) | |
artist = re.search('string "xesam:artist" variant array \[ string "(.+?)"', metadata).group(1) | |
title = re.search('string "xesam:title" variant string "(.+?)"', metadata).group(1) | |
name = artist + ' - ' + title | |
return track_id, name | |
def notify(msg, icon='face-surprise'): | |
cmd = ['notify-send', '-i', icon, msg] | |
subprocess.call(cmd) | |
if __name__ == '__main__': | |
try: | |
tid, name = get_current_track_and_name() | |
except subprocess.CalledProcessError: | |
notify("Couldn't find any songs playing", icon='error') | |
sys.exit(1) | |
assert 'spotify:track' in tid, "got corrupt track id" | |
print("got tid, name", tid, name) | |
tracks = [tid] | |
pprint(api.user_playlist_remove_all_occurrences_of_tracks(USER, PLAYLIST, tracks)) | |
pprint(api.user_playlist_add_tracks(USER, PLAYLIST, tracks)) | |
notify("Added %s" % name) | |
sample_metadata = """ | |
method return time=1464890202.485689 sender=:1.248 -> destination=:1.347 serial=577 reply_serial=2 | |
variant array [ | |
dict entry( | |
string "mpris:trackid" | |
variant string "spotify:track:7p9dd71JR2ucoAuO1Sy0VZ" | |
) | |
dict entry( | |
string "mpris:length" | |
variant uint64 204920000 | |
) | |
dict entry( | |
string "mpris:artUrl" | |
variant string "https://open.spotify.com/image/435bd64fba14f5ef94a1ee27521fe64c90ea3a8f" | |
) | |
dict entry( | |
string "xesam:album" | |
variant string "On A Day Like Today" | |
) | |
dict entry( | |
string "xesam:albumArtist" | |
variant array [ | |
string "Bryan Adams" | |
] | |
) | |
dict entry( | |
string "xesam:artist" | |
variant array [ | |
string "Bryan Adams" | |
] | |
) | |
dict entry( | |
string "xesam:autoRating" | |
variant double 0.63 | |
) | |
dict entry( | |
string "xesam:discNumber" | |
variant int32 1 | |
) | |
dict entry( | |
string "xesam:title" | |
variant string "When You're Gone" | |
) | |
dict entry( | |
string "xesam:trackNumber" | |
variant int32 8 | |
) | |
dict entry( | |
string "xesam:url" | |
variant string "https://open.spotify.com/track/7p9dd71JR2ucoAuO1Sy0VZ" | |
) | |
] | |
""" |
Something else I had trouble with was authorizing this script to work with spotify, what you need to do is allow the script here https://developer.spotify.com/my-applications/#!/applications
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I had some trouble making this work with a keyboard shortcut so what I did is made a file called url with only the token URL you get when you run it in terminal, and making the keyboard shortcut run
python ~/<path-to-url>/add-current-spotify-song-to-favorites.py ~/<path-to-url>/url