weskerfoot/Spotify-MPD-Sync

Spotify-MPD-Sync not working

Closed this issue · 11 comments

Hi @weskerfoot ,

First of all, thanks for the solution, as I think that once I fix this issue, it will be working fine.

I have downloaded the code and executed but I'm not getting any list on my mpd. Doing some debugging, the issue is with the line #35,

playlists = self.sp.user_playlists(self.username)

I have followed the steps on the README, but this call to the API is answering blank. I think that the issue is that my user does not have allowed the newly created app to see my playlists. Could this be the issue?

Thanks for trying it out!
Could you test it by doing this in a bash script, just to make sure things are getting passed in properly?

#! /usr/bin/env bash
SPOTIPY_CLIENT_ID='YOUR_CLIENT_ID'
SPOTIPY_CLIENT_SECRET='YOUR_CLIENT_SECRET'
SPOTIPY_REDIRECT_URI='http://localhost'
SPOTIFY_USERNAME='YOUR_SPOTIFY_USERNAME'
spotsync

Then obviously just substitute those variables with yours.

Also, you will need ~/.local/bin in your $PATH just in case that's not already the case.

The SPOTIPY_CLIENT_ID and SPOTIPY_CLIENT_SECRET variables are the ones that are supposed to allow that API call to work, so unless there is something wrong with the Spotify API, and as long as you created the Spotify application in your dashboard (https://developer.spotify.com/dashboard/applications) it should work ok.

Do you get any error messages from the Spotify API showing up when you run it?

I thought about packaging this up as a systemd unit or something so that it would run daily and you wouldn't have to worry about environment variables, but then again not everyone would be using a system that supports it (e.g. MacOS).

This is the executable file that I have created to call spotsync, it sits on my home folder of a linux server that is not the mopidy server.

#! /usr/bin/env bash
SPOTIPY_CLIENT_ID='XXXXXXXXXXXXXX'
SPOTIPY_CLIENT_SECRET='YYYYYYYYYY'
SPOTIPY_REDIRECT_URI='http://aaa.bbb.ccc.ddd'
SPOTIFY_USERNAME='dddddd'
~/.local/bin/spotsync

Because the mpidy server is not the same as the script is being execute, I have changed the line 20:

self.mpd_client.connect("127.0.0.1", 6600)

by

self.mpd_client.connect("aaa.bbb.ccc.ddd", 6600)

And yes, the port 6600 is opened because when i try to connect, the server answers the following:

OK MPD 0.19.0
ACK [5@0] {None} Invalid word character
ACK [5@0] {None} Invalid word character
ACK [5@0] {None} Invalid word character
ACK [5@0] {None} Invalid word character
ACK [5@0] {None} Invalid word character
ACK [5@0] {None} Invalid word character
ACK [5@0] {None} Invalid word character
ACK [5@0] {None} Invalid word character
ACK [5@0] {None} Invalid word character
ACK [5@0] {} No command given`

Anyhow, when I execute the code, nothing is returned. Executing the code manually, here is the ouput:

λ xxx@yyy ~/Spotify-MPD-Sync-master λ env
HOME=/home/xxx
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
MAIL=/var/mail/xxx
SHELL=/bin/zsh
LANG=en_US.UTF-8
SHLVL=1
PWD=/home/xxx/Spotify-MPD-Sync-master
OLDPWD=/home/xxx
ZSH=/home/xxx/.oh-my-zsh
PAGER=less
LESS=-R
SPOTIPY_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxx
SPOTIPY_CLIENT_SECRET=yyyyyyyyyyyyyyyyyyyyyy
SPOTIPY_REDIRECT_URI=http://aaa.bbb.ccc.ddd
SPOTIFY_USERNAME=uuuuuuuuuu
_=/usr/bin/env
λ xxx@yyy ~/Spotify-MPD-Sync-master λ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
from mpd import MPDClient
from mpd.base import CommandError
from collections import defaultdict
from re import sub
from os import environ
username = environ.get("SPOTIFY_USERNAME")
client_credentials_manager = SpotifyClientCredentials()
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
mpd_client = MPDClient()
mpd_client.connect("aaa.bbb.ccc.ddd", 6600)
sp.user_playlists(username)
{'href': 'https://api.spotify.com/v1/users/uuuuuuuuuu/playlists?offset=0&limit=50', 'items': [], 'limit': 50, 'next': None, 'offset': 0, 'previous': None, 'total': 0}

Ah, ok, yes it does look like there may be something wrong with the Spotify API. I can try looking into it a bit more myself.

I am going to make that server value configurable from the command line soon.

Ok yes it is most likely because I was using the "Client Credentials Flow" and not the "Authorization Code Flow" which allows access to private playlists.

I'm working on a fix for that, thanks for opening this issue!

I will also look into into that.

This git code or this one shows how to use spotipy, but it looks like we need some sort of web integration.

Very crude code that is working:

import os
from spotipy import oauth2
import spotipy
client_id = os.getenv('SPOTIPY_CLIENT_ID')
client_secret = os.getenv('SPOTIPY_CLIENT_SECRET')
redirect_uri = os.getenv('SPOTIPY_REDIRECT_URI')
username = os.getenv('USERNAME')
cache_path = ".cache-"+str(os.getenv('USERNAME'))
scope = 'user-library-read playlist-read-private user-read-currently-playing'
sp_oauth = oauth2.SpotifyOAuth(client_id, client_secret, redirect_uri, scope=scope, cache_path=cache_path)
auth_url = sp_oauth.get_authorize_url()
print(auth_url)
response = input("Enter the URL you were redirected to: ")
code = sp_oauth.parse_response_code(response)
token_info = sp_oauth.get_access_token(code)
access_token = token_info['access_token']
sp = spotipy.Spotify(access_token)
sp.current_user()
sp.user_playlists(username)

On the creation of the application on spotify looks like that you have to add the SPOTIPY_REDIRECT_URI as a Redirect URIs. If we can open a port on the same server than Mopidy, we can get the redirection from Spotify automatically

Mi very simple, bad, and humble implementation:

spotify.py

As you can see, my quality code is very bad. I have also changed self.sp.user_playlists for self.sp.current_user_playlists() as I want all the lists that I'm following, not only the ones that I have created.

Now the problem I'm facing is the following error:

Llegando a Casa has missing tracks, trying to add them
[0@0] {playlistclear} Not implemented
[0@0] {playlistadd} Not implemented
Could not add spotify:track:1Pw5C4N6Fn5E4mGCxmbbVa

I will work into that tomorrow.

Thanks!

@NachoParra thanks! I had come up with something similar. For reference, there is a function util.prompt_for_user_token that I will likely end up using (or I may run an ephemeral web server to authenticate). Either way, it will require whitelisting the callback URL used so the instructions will need to be updated.

This is working in #3 but still needs work to clean up the documentation and make everything configurable

Should be fixed now in master. It will use a new flow involving opening up your browser and allowing access to spotify. See the README for details.